home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / ATL / include / Atlctl.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  97.9 KB  |  3,496 lines

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10.  
  11. #ifndef __ATLCTL_H__
  12. #define __ATLCTL_H__
  13.  
  14. #ifndef __cplusplus
  15.     #error ATL requires C++ compilation (use a .cpp suffix)
  16. #endif
  17.  
  18. #include <atlwin.h>
  19.  
  20. #if defined(_WIN32_WCE)
  21.     #ifdef ATL_USE_URLMON
  22.         #include <objsafe.h>
  23.         #include <urlmon.h>
  24.     #endif
  25. #else // _WIN32_WCE
  26. #include <objsafe.h>
  27. #include <urlmon.h>
  28.  
  29. #pragma comment(lib, "gdi32.lib")
  30. #pragma comment(lib, "urlmon.lib")
  31. #endif // _WIN32_WCE
  32.  
  33.  
  34. #define DECLARE_VIEW_STATUS(statusFlags) \
  35.     DWORD _GetViewStatus() \
  36.     { \
  37.         return statusFlags; \
  38.     }
  39.  
  40. // Include GUIDs for the new stock property dialogs contained in the dll MSStkProp.DLL
  41. #if !defined(_WIN32_WCE)
  42. #include "msstkppg.h"
  43. #include "atliface.h"
  44. #define CLSID_MSStockFont CLSID_StockFontPage
  45. #define CLSID_MSStockColor CLSID_StockColorPage
  46. #define CLSID_MSStockPicture CLSID_StockPicturePage
  47. #endif // _WIN32_WCE
  48.  
  49. struct ATL_DRAWINFO
  50. {
  51.     UINT cbSize;
  52.     DWORD dwDrawAspect;
  53.     LONG lindex;
  54.     DVTARGETDEVICE* ptd;
  55.     HDC hicTargetDev;
  56.     HDC hdcDraw;
  57.     LPCRECTL prcBounds; //Rectangle in which to draw
  58.     LPCRECTL prcWBounds; //WindowOrg and Ext if metafile
  59.     BOOL bOptimize;
  60.     BOOL bZoomed;
  61.     BOOL bRectInHimetric;
  62.     SIZEL ZoomNum;      //ZoomX = ZoomNum.cx/ZoomNum.cy
  63.     SIZEL ZoomDen;
  64. };
  65.  
  66. namespace ATL
  67. {
  68.  
  69. #pragma pack(push, _ATL_PACKING)
  70.  
  71. // Forward declarations
  72. //
  73. class ATL_NO_VTABLE CComControlBase;
  74. template <class T, class WinBase> class CComControl;
  75.  
  76. //////////////////////////////////////////////////////////////////////////////
  77. // CFirePropNotifyEvent
  78.  
  79.  
  80. // Helper functions for safely communicating with objects who sink IPropertyNotifySink
  81. class CFirePropNotifyEvent
  82. {
  83. public:
  84.     // Ask any objects sinking the IPropertyNotifySink notification if it is ok to edit a specified property
  85.     static HRESULT FireOnRequestEdit(IUnknown* pUnk, DISPID dispID)
  86.     {
  87.         CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC(pUnk);
  88.         if (!pCPC)
  89.             return S_OK;
  90.         CComPtr<IConnectionPoint> pCP;
  91.         pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);
  92.         if (!pCP)
  93.             return S_OK;
  94.         CComPtr<IEnumConnections> pEnum;
  95.  
  96.         if (FAILED(pCP->EnumConnections(&pEnum)))
  97.             return S_OK;
  98.         CONNECTDATA cd;
  99.         while (pEnum->Next(1, &cd, NULL) == S_OK)
  100.         {
  101.             if (cd.pUnk)
  102.             {
  103.                 HRESULT hr = S_OK;
  104.                 CComQIPtr<IPropertyNotifySink, &IID_IPropertyNotifySink> pSink(cd.pUnk);
  105.                 if (pSink)
  106.                     hr = pSink->OnRequestEdit(dispID);
  107.                 cd.pUnk->Release();
  108.                 if (hr == S_FALSE)
  109.                     return S_FALSE;
  110.             }
  111.         }
  112.         return S_OK;
  113.     }
  114.  
  115.     // Notify any objects sinking the IPropertyNotifySink notification that a property has changed
  116.     static HRESULT FireOnChanged(IUnknown* pUnk, DISPID dispID)
  117.     {
  118.         CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC(pUnk);
  119.         if (!pCPC)
  120.             return S_OK;
  121.         CComPtr<IConnectionPoint> pCP;
  122.         pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);
  123.         if (!pCP)
  124.             return S_OK;
  125.         CComPtr<IEnumConnections> pEnum;
  126.  
  127.         if (FAILED(pCP->EnumConnections(&pEnum)))
  128.             return S_OK;
  129.         CONNECTDATA cd;
  130.         while (pEnum->Next(1, &cd, NULL) == S_OK)
  131.         {
  132.             if (cd.pUnk)
  133.             {
  134.                 CComQIPtr<IPropertyNotifySink, &IID_IPropertyNotifySink> pSink(cd.pUnk);
  135.                 if (pSink)
  136.                     pSink->OnChanged(dispID);
  137.                 cd.pUnk->Release();
  138.             }
  139.         }
  140.         return S_OK;
  141.     }
  142. };
  143.  
  144.  
  145. //////////////////////////////////////////////////////////////////////////////
  146. // CComControlBase
  147.  
  148. // Holds the essential data members for an ActiveX control and useful helper functions
  149. class ATL_NO_VTABLE CComControlBase
  150. {
  151. public:
  152.     CComControlBase(HWND& h) : m_hWndCD(h)
  153.     {
  154.         memset(this, 0, sizeof(CComControlBase));
  155.         m_phWndCD = &h;
  156.         m_sizeExtent.cx = 2*2540;
  157.         m_sizeExtent.cy = 2*2540;
  158.         m_sizeNatural = m_sizeExtent;
  159.     }
  160.     ~CComControlBase()
  161.     {
  162.         if (m_hWndCD != NULL)
  163.             ::DestroyWindow(m_hWndCD);
  164.         ATLTRACE2(atlTraceControls,2,_T("Control Destroyed\n"));
  165.     }
  166.  
  167. // methods
  168. public:
  169.     // Control helper functions can go here non-virtuals only please
  170.  
  171.     // Mark the control 'dirty' so the container will save it
  172.     void SetDirty(BOOL bDirty)
  173.     {
  174.         m_bRequiresSave = bDirty;
  175.     }
  176.     // Obtain the dirty state for the control 
  177.     BOOL GetDirty()
  178.     {
  179.         return m_bRequiresSave ? TRUE : FALSE;
  180.     }
  181.     // Get the zoom factor (numerator & denominator) which is factor of the natural extent
  182.     void GetZoomInfo(ATL_DRAWINFO& di);
  183.     // Sends a notification that the moniker for the control has changed
  184.     HRESULT SendOnRename(IMoniker *pmk)
  185.     {
  186.         HRESULT hRes = S_OK;
  187.         if (m_spOleAdviseHolder)
  188.             hRes = m_spOleAdviseHolder->SendOnRename(pmk);
  189.         return hRes;
  190.     }
  191.     // Sends a notification that the control has just saved its data
  192.     HRESULT SendOnSave()
  193.     {
  194.         HRESULT hRes = S_OK;
  195.         if (m_spOleAdviseHolder)
  196.             hRes = m_spOleAdviseHolder->SendOnSave();
  197.         return hRes;
  198.     }
  199.     // Sends a notification that the control has closed its advisory sinks
  200.     HRESULT SendOnClose()
  201.     {
  202.         HRESULT hRes = S_OK;
  203.         if (m_spOleAdviseHolder)
  204.             hRes = m_spOleAdviseHolder->SendOnClose();
  205.         return hRes;
  206.     }
  207.     // Sends a notification that the control's data has changed
  208.     HRESULT SendOnDataChange(DWORD advf = 0);
  209.     // Sends a notification that the control's representation has changed
  210.     HRESULT SendOnViewChange(DWORD dwAspect, LONG lindex = -1)
  211.     {
  212.         if (m_spAdviseSink)
  213.             m_spAdviseSink->OnViewChange(dwAspect, lindex);
  214.         return S_OK;
  215.     }
  216.     // Sends a notification to the container that the control has received focus
  217.     LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  218.     {
  219.         if (m_bInPlaceActive)
  220.         {
  221.             CComPtr<IOleObject> pOleObject;
  222.             ControlQueryInterface(IID_IOleObject, (void**)&pOleObject);
  223.             if (pOleObject != NULL)
  224.                 pOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_spClientSite, 0, m_hWndCD, &m_rcPos);
  225.             CComQIPtr<IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  226.             if (m_bInPlaceActive && spSite != NULL)
  227.                 spSite->OnFocus(TRUE);
  228.         }
  229.         bHandled = FALSE;
  230.         return 1;
  231.     }
  232.     LRESULT OnKillFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  233.     {
  234.         CComQIPtr<IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  235.         if (m_bInPlaceActive && spSite != NULL && !::IsChild(m_hWndCD, ::GetFocus()))
  236.             spSite->OnFocus(FALSE);
  237.         bHandled = FALSE;
  238.         return 1;
  239.     }
  240.     LRESULT OnMouseActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  241.     {
  242.         BOOL bUserMode = TRUE;
  243.         HRESULT hRet = GetAmbientUserMode(bUserMode);
  244.         // UI activate if in user mode only
  245.         // allow activation if we can't determine mode
  246.         if (FAILED(hRet) || bUserMode)
  247.         {
  248.             CComPtr<IOleObject> pOleObject;
  249.             ControlQueryInterface(IID_IOleObject, (void**)&pOleObject);
  250.             if (pOleObject != NULL)
  251.                 pOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_spClientSite, 0, m_hWndCD, &m_rcPos);
  252.         }
  253.         bHandled = FALSE;
  254.         return 1;
  255.     }
  256.     BOOL PreTranslateAccelerator(LPMSG /*pMsg*/, HRESULT& /*hRet*/)
  257.     {
  258.         return FALSE;
  259.     }
  260.  
  261.     HRESULT GetAmbientProperty(DISPID dispid, VARIANT& var)
  262.     {
  263.         HRESULT hRes = E_FAIL;
  264.         if (m_spAmbientDispatch.p != NULL)
  265.             hRes = m_spAmbientDispatch.GetProperty(dispid, &var);
  266.         return hRes;
  267.     }
  268.     HRESULT GetAmbientAppearance(short& nAppearance)
  269.     {
  270.         CComVariant var;
  271.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_APPEARANCE, var);
  272.         ATLASSERT(var.vt == VT_I2 || var.vt == VT_UI2 || var.vt == VT_I4 || var.vt == VT_UI4 || FAILED(hRes));
  273.         nAppearance = var.iVal;
  274.         return hRes;
  275.     }
  276.     HRESULT GetAmbientBackColor(OLE_COLOR& BackColor)
  277.     {
  278.         CComVariant var;
  279.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_BACKCOLOR, var);
  280.         ATLASSERT(var.vt == VT_I4 || var.vt == VT_UI4 || FAILED(hRes));
  281.         BackColor = var.lVal;
  282.         return hRes;
  283.     }
  284.     HRESULT GetAmbientDisplayName(BSTR& bstrDisplayName)
  285.     {
  286.         CComVariant var;
  287.         if (bstrDisplayName)
  288.         {
  289.             SysFreeString(bstrDisplayName);
  290.             bstrDisplayName = NULL;
  291.         }
  292.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYNAME, var);
  293.         if (SUCCEEDED(hRes))
  294.         {
  295.             if (var.vt != VT_BSTR)
  296.                 return E_FAIL;
  297.             bstrDisplayName = var.bstrVal;
  298.             var.vt = VT_EMPTY;
  299.             var.bstrVal = NULL;
  300.         }
  301.         return hRes;
  302.     }
  303.     HRESULT GetAmbientFont(IFont** ppFont)
  304.     {
  305.         // caller MUST Release the font!
  306.         if (ppFont == NULL)
  307.             return E_POINTER;
  308.         *ppFont = NULL;
  309.         CComVariant var;
  310.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FONT, var);
  311.         ATLASSERT((var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH) || FAILED(hRes));
  312.         if (SUCCEEDED(hRes) && var.pdispVal)
  313.         {
  314.             if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH)
  315.                 hRes = var.pdispVal->QueryInterface(IID_IFont, (void**)ppFont);
  316.             else
  317.                 hRes = DISP_E_BADVARTYPE;
  318.         }
  319.         return hRes;
  320.     }
  321.     HRESULT GetAmbientFontDisp(IFontDisp** ppFont)
  322.     {
  323.         // caller MUST Release the font!
  324.         if (ppFont == NULL)
  325.             return E_POINTER;
  326.         *ppFont = NULL;
  327.         CComVariant var;
  328.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FONT, var);
  329.         ATLASSERT((var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH) || FAILED(hRes));
  330.         if (SUCCEEDED(hRes) && var.pdispVal)
  331.         {
  332.             if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH)
  333.                 hRes = var.pdispVal->QueryInterface(IID_IFontDisp, (void**)ppFont);
  334.             else
  335.                 hRes = DISP_E_BADVARTYPE;
  336.         }
  337.         return hRes;
  338.     }
  339.     HRESULT GetAmbientForeColor(OLE_COLOR& ForeColor)
  340.     {
  341.         CComVariant var;
  342.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_FORECOLOR, var);
  343.         ATLASSERT(var.vt == VT_I4 || var.vt == VT_UI4 || FAILED(hRes));
  344.         ForeColor = var.lVal;
  345.         return hRes;
  346.     }
  347.     HRESULT GetAmbientLocaleID(LCID& lcid)
  348.     {
  349.         CComVariant var;
  350.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_LOCALEID, var);
  351.         ATLASSERT((var.vt == VT_UI4 || var.vt == VT_I4) || FAILED(hRes));
  352.         lcid = var.lVal;
  353.         return hRes;
  354.     }
  355.     HRESULT GetAmbientScaleUnits(BSTR& bstrScaleUnits)
  356.     {
  357.         CComVariant var;
  358.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SCALEUNITS, var);
  359.         ATLASSERT(var.vt == VT_BSTR || FAILED(hRes));
  360.         bstrScaleUnits = var.bstrVal;
  361.         return hRes;
  362.     }
  363.     HRESULT GetAmbientTextAlign(short& nTextAlign)
  364.     {
  365.         CComVariant var;
  366.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_TEXTALIGN, var);
  367.         ATLASSERT(var.vt == VT_I2 || FAILED(hRes));
  368.         nTextAlign = var.iVal;
  369.         return hRes;
  370.     }
  371.     HRESULT GetAmbientUserMode(BOOL& bUserMode)
  372.     {
  373.         CComVariant var;
  374.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_USERMODE, var);
  375.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  376.         bUserMode = var.boolVal;
  377.         return hRes;
  378.     }
  379.     HRESULT GetAmbientUIDead(BOOL& bUIDead)
  380.     {
  381.         CComVariant var;
  382.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_UIDEAD, var);
  383.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  384.         bUIDead = var.boolVal;
  385.         return hRes;
  386.     }
  387.     HRESULT GetAmbientShowGrabHandles(BOOL& bShowGrabHandles)
  388.     {
  389.         CComVariant var;
  390.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWGRABHANDLES, var);
  391.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  392.         bShowGrabHandles = var.boolVal;
  393.         return hRes;
  394.     }
  395.     HRESULT GetAmbientShowHatching(BOOL& bShowHatching)
  396.     {
  397.         CComVariant var;
  398.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SHOWHATCHING, var);
  399.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  400.         bShowHatching = var.boolVal;
  401.         return hRes;
  402.     }
  403.     HRESULT GetAmbientMessageReflect(BOOL& bMessageReflect)
  404.     {
  405.         CComVariant var;
  406.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_MESSAGEREFLECT, var);
  407.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  408.         bMessageReflect = var.boolVal;
  409.         return hRes;
  410.     }
  411.     HRESULT GetAmbientAutoClip(BOOL& bAutoClip)
  412.     {
  413.         CComVariant var;
  414.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_AUTOCLIP, var);
  415.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  416.         bAutoClip = var.boolVal;
  417.         return hRes;
  418.     }
  419.     HRESULT GetAmbientDisplayAsDefault(BOOL& bDisplaysDefault)
  420.     {
  421.         CComVariant var;
  422.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_DISPLAYASDEFAULT, var);
  423.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  424.         bDisplaysDefault = var.boolVal;
  425.         return hRes;
  426.     }
  427.     HRESULT GetAmbientSupportsMnemonics(BOOL& bSupportMnemonics)
  428.     {
  429.         CComVariant var;
  430.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_SUPPORTSMNEMONICS, var);
  431.         ATLASSERT(var.vt == VT_BOOL || FAILED(hRes));
  432.         bSupportMnemonics = var.boolVal;
  433.         return hRes;
  434.     }
  435.     HRESULT GetAmbientPalette(HPALETTE& hPalette)
  436.     {
  437.         CComVariant var;
  438.         HRESULT hRes = GetAmbientProperty(DISPID_AMBIENT_PALETTE, var);
  439.         ATLASSERT(var.vt == VT_I4 || var.vt == VT_UI4 || FAILED(hRes));
  440.         hPalette = reinterpret_cast<HPALETTE>(var.lVal);
  441.         return hRes;
  442.     }
  443.  
  444.     HRESULT InternalGetSite(REFIID riid, void** ppUnkSite)
  445.     {
  446.         ATLASSERT(ppUnkSite != NULL);
  447.         if (ppUnkSite == NULL)
  448.             return E_POINTER;
  449.         if (m_spClientSite == NULL)
  450.         {
  451.             *ppUnkSite = NULL;
  452.             return S_OK;
  453.         }
  454.         return m_spClientSite->QueryInterface(riid, ppUnkSite);
  455.     }
  456.  
  457.     BOOL DoesVerbUIActivate(LONG iVerb)
  458.     {
  459.         BOOL b = FALSE;
  460.         switch (iVerb)
  461.         {
  462.             case OLEIVERB_UIACTIVATE:
  463.             case OLEIVERB_PRIMARY:
  464.                 b = TRUE;
  465.                 break;
  466.         }
  467.         // if no ambient dispatch then in old style OLE container
  468.         if (DoesVerbActivate(iVerb) && m_spAmbientDispatch.p == NULL)
  469.             b = TRUE;
  470.         return b;
  471.     }
  472.  
  473.     BOOL DoesVerbActivate(LONG iVerb)
  474.     {
  475.         BOOL b = FALSE;
  476.         switch (iVerb)
  477.         {
  478.             case OLEIVERB_UIACTIVATE:
  479.             case OLEIVERB_PRIMARY:
  480.             case OLEIVERB_SHOW:
  481.             case OLEIVERB_INPLACEACTIVATE:
  482.                 b = TRUE;
  483.                 break;
  484.         }
  485.         return b;
  486.     }
  487.  
  488.     BOOL SetControlFocus(BOOL bGrab);
  489.     HRESULT IQuickActivate_QuickActivate(QACONTAINER *pQACont,
  490.         QACONTROL *pQACtrl);
  491.     HRESULT DoVerbProperties(LPCRECT /* prcPosRect */, HWND hwndParent);
  492.     HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect = NULL);
  493.  
  494.     HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite);
  495.     HRESULT IOleObject_GetClientSite(IOleClientSite **ppClientSite);
  496.     HRESULT IOleObject_Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection);
  497.     HRESULT IOleObject_Close(DWORD dwSaveOption);
  498.     HRESULT IOleObject_SetExtent(DWORD dwDrawAspect, SIZEL *psizel);
  499.     HRESULT IOleInPlaceObject_InPlaceDeactivate(void);
  500.     HRESULT IOleInPlaceObject_UIDeactivate(void);
  501.     HRESULT IOleInPlaceObject_SetObjectRects(LPCRECT prcPos,LPCRECT prcClip);
  502.     HRESULT IViewObject_Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
  503.         DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  504.         LPCRECTL prcBounds, LPCRECTL prcWBounds);
  505.     HRESULT IDataObject_GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
  506.  
  507.     HRESULT FireViewChange();
  508.     LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& lResult);
  509.  
  510.     virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos) = 0;
  511.     virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv) = 0;
  512.     virtual HRESULT OnDrawAdvanced(ATL_DRAWINFO& di);
  513.     virtual HRESULT OnDraw(ATL_DRAWINFO& /*di*/)
  514.     {
  515.         return S_OK;
  516.     }
  517.  
  518.  
  519. // Attributes
  520. public:
  521.     CComPtr<IOleInPlaceSiteWindowless> m_spInPlaceSite;
  522.     CComPtr<IDataAdviseHolder> m_spDataAdviseHolder;
  523.     CComPtr<IOleAdviseHolder> m_spOleAdviseHolder;
  524.     CComPtr<IOleClientSite> m_spClientSite;
  525.     CComPtr<IAdviseSink> m_spAdviseSink;
  526.     CComDispatchDriver m_spAmbientDispatch;
  527.  
  528.     SIZE m_sizeNatural; //unscaled size in himetric
  529.     SIZE m_sizeExtent;  //current extents in himetric
  530.     RECT m_rcPos; // position in pixels
  531. #pragma warning(disable: 4510 4610) // unnamed union
  532.     union
  533.     {
  534.         HWND& m_hWndCD;
  535.         HWND* m_phWndCD;
  536.     };
  537. #pragma warning(default: 4510 4610)
  538.     union
  539.     {
  540.         // m_nFreezeEvents is the only one actually used
  541.         int m_nFreezeEvents; // count of freezes versus thaws
  542.  
  543.         // These are here to make stock properties work
  544.         IPictureDisp* m_pMouseIcon;
  545.         IPictureDisp* m_pPicture;
  546.         IFontDisp* m_pFont;
  547.         OLE_COLOR m_clrBackColor;
  548.         OLE_COLOR m_clrBorderColor;
  549.         OLE_COLOR m_clrFillColor;
  550.         OLE_COLOR m_clrForeColor;
  551.         BSTR m_bstrText;
  552.         BSTR m_bstrCaption;
  553.         BOOL m_bValid;
  554.         BOOL m_bTabStop;
  555.         BOOL m_bBorderVisible;
  556.         BOOL m_bEnabled;
  557.         LONG m_nBackStyle;
  558.         LONG m_nBorderStyle;
  559.         LONG m_nBorderWidth;
  560.         LONG m_nDrawMode;
  561.         LONG m_nDrawStyle;
  562.         LONG m_nDrawWidth;
  563.         LONG m_nFillStyle;
  564.         SHORT m_nAppearance;
  565.         LONG m_nMousePointer;
  566.         LONG m_nReadyState;
  567.     };
  568.  
  569.     unsigned m_bNegotiatedWnd:1;
  570.     unsigned m_bWndLess:1;
  571.     unsigned m_bInPlaceActive:1;
  572.     unsigned m_bUIActive:1;
  573.     unsigned m_bUsingWindowRgn:1;
  574.     unsigned m_bInPlaceSiteEx:1;
  575.     unsigned m_bWindowOnly:1;
  576.     unsigned m_bRequiresSave:1;
  577.     unsigned m_bWasOnceWindowless:1;
  578.     unsigned m_bAutoSize:1; //SetExtent fails if size doesn't match existing
  579.     unsigned m_bRecomposeOnResize:1; //implies OLEMISC_RECOMPOSEONRESIZE
  580.     unsigned m_bResizeNatural:1;  //resize natural extent on SetExtent
  581.     unsigned m_bDrawFromNatural:1; //instead of m_sizeExtent
  582.     unsigned m_bDrawGetDataInHimetric:1; //instead of pixels
  583.  
  584.     DECLARE_VIEW_STATUS(VIEWSTATUS_OPAQUE)
  585. };
  586.  
  587. inline HRESULT CComControlBase::IQuickActivate_QuickActivate(QACONTAINER *pQACont,
  588.     QACONTROL *pQACtrl)
  589. {
  590.     ATLASSERT(pQACont != NULL);
  591.     ATLASSERT(pQACtrl != NULL);
  592.     if (!pQACont || !pQACtrl)
  593.         return E_POINTER;
  594.  
  595.     HRESULT hRes;
  596.     ULONG uCB = pQACtrl->cbSize;
  597.     memset(pQACtrl, 0, uCB);
  598.     pQACtrl->cbSize = uCB;
  599.  
  600.     // get all interfaces we are going to need
  601.     CComPtr<IOleObject> pOO;
  602.     ControlQueryInterface(IID_IOleObject, (void**)&pOO);
  603.     CComPtr<IViewObjectEx> pVOEX;
  604.     ControlQueryInterface(IID_IViewObjectEx, (void**)&pVOEX);
  605.     CComPtr<IPointerInactive> pPI;
  606.     ControlQueryInterface(IID_IPointerInactive, (void**)&pPI);
  607.     CComPtr<IProvideClassInfo2> pPCI;
  608.     ControlQueryInterface(IID_IProvideClassInfo2, (void**)&pPCI);
  609.  
  610.     if (pOO == NULL || pVOEX == NULL)
  611.         return E_FAIL;
  612.  
  613.     pOO->SetClientSite(pQACont->pClientSite);
  614.  
  615.     if (pQACont->pAdviseSink != NULL)
  616.     {
  617.         ATLTRACE2(atlTraceControls,2,_T("Setting up IOleObject Advise\n"));
  618.         pVOEX->SetAdvise(DVASPECT_CONTENT, 0, pQACont->pAdviseSink);
  619.     }
  620.  
  621.     CComPtr<IConnectionPointContainer> pCPC;
  622.     ControlQueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  623.  
  624.     if (pQACont->pPropertyNotifySink)
  625.     {
  626.         ATLTRACE2(atlTraceControls,2,_T("Setting up PropNotify CP\n"));
  627.         CComPtr<IConnectionPoint> pCP;
  628.         if (pCPC != NULL)
  629.         {
  630.             hRes = pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);
  631.             if (SUCCEEDED(hRes))
  632.                 pCP->Advise(pQACont->pPropertyNotifySink, &pQACtrl->dwPropNotifyCookie);
  633.         }
  634.     }
  635.  
  636.     if (pPCI)
  637.     {
  638.         GUID iidDefaultSrc;
  639.         if (SUCCEEDED(pPCI->GetGUID(GUIDKIND_DEFAULT_SOURCE_DISP_IID,
  640.             &iidDefaultSrc)))
  641.         {
  642.             if (pQACont->pUnkEventSink)
  643.             {
  644.                 ATLTRACE2(atlTraceControls,2,_T("Setting up Default Out Going Interface\n"));
  645.                 CComPtr<IConnectionPoint> pCP;
  646.                 if (pCPC != NULL)
  647.                 {
  648.                     hRes = pCPC->FindConnectionPoint(iidDefaultSrc, &pCP);
  649.                     if (SUCCEEDED(hRes))
  650.                         pCP->Advise(pQACont->pUnkEventSink, &pQACtrl->dwEventCookie);
  651.                 }
  652.             }
  653.         }
  654.     }
  655.     // give information to container
  656.     if (pOO != NULL)
  657.         pOO->GetMiscStatus(DVASPECT_CONTENT, &pQACtrl->dwMiscStatus);
  658.  
  659.     if (pVOEX != NULL)
  660.         pVOEX->GetViewStatus(&pQACtrl->dwViewStatus);
  661.  
  662.     if (pPI != NULL)
  663.         pPI->GetActivationPolicy(&pQACtrl->dwPointerActivationPolicy);
  664.     return S_OK;
  665. }
  666.  
  667. inline BOOL CComControlBase::SetControlFocus(BOOL bGrab)
  668. {
  669.     if (m_bWndLess)
  670.     {
  671.         if (!m_bUIActive && bGrab)
  672.             if (FAILED(InPlaceActivate(OLEIVERB_UIACTIVATE)))
  673.                 return FALSE;
  674.  
  675.         return (m_spInPlaceSite->SetFocus(bGrab) == S_OK);
  676.     }
  677.     else
  678.     {
  679.         // we've got a window.
  680.         //
  681.         if (m_bInPlaceActive)
  682.         {
  683.             HWND hwnd = (bGrab) ? m_hWndCD : ::GetParent(m_hWndCD);
  684.             if (!m_bUIActive && bGrab)
  685.                 return SUCCEEDED(InPlaceActivate(OLEIVERB_UIACTIVATE));
  686.             else
  687.             {
  688.                 if (!::IsChild(hwnd, ::GetFocus()))
  689.                     ::SetFocus(hwnd);
  690.                 return TRUE;
  691.             }
  692.         }
  693.     }
  694.     return FALSE;
  695. }
  696.  
  697. inline HRESULT CComControlBase::DoVerbProperties(LPCRECT /* prcPosRect */, HWND hwndParent)
  698. {
  699. #if defined(_WIN32_WCE)
  700. // WinCE: no OleCreatePropertyFrame
  701.     RETAILMSG(1, (TEXT("CComControlBase::DoVerbProperties: Not implemented\r\n")));
  702.     return E_NOTIMPL;
  703. #else // _WIN32_WCE
  704.     HRESULT hr = S_OK;
  705.     CComQIPtr <ISpecifyPropertyPages, &IID_ISpecifyPropertyPages> spPages;
  706.     CComQIPtr <IOleObject, &IID_IOleObject> spObj;
  707.     CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  708.  
  709.     if (spSite)
  710.     {
  711.         hr = spSite->ShowPropertyFrame();
  712.         if (SUCCEEDED(hr))
  713.             return hr;
  714.     }
  715.  
  716.     CComPtr<IUnknown> pUnk;
  717.     ControlQueryInterface(IID_IUnknown, (void**)&pUnk);
  718.     ATLASSERT(pUnk != NULL);
  719.     CAUUID pages;
  720.     spPages = pUnk;
  721.     if (spPages)
  722.     {
  723.         hr = spPages->GetPages(&pages);
  724.         if (SUCCEEDED(hr))
  725.         {
  726.             spObj = pUnk;
  727.             if (spObj)
  728.             {
  729.                 LPOLESTR szTitle = NULL;
  730.  
  731.                 spObj->GetUserType(USERCLASSTYPE_SHORT, &szTitle);
  732.  
  733.                 LCID lcid;
  734.                 if (FAILED(GetAmbientLocaleID(lcid)))
  735.                     lcid = LOCALE_USER_DEFAULT;
  736.  
  737.                 hr = OleCreatePropertyFrame(hwndParent, m_rcPos.top, m_rcPos.left, szTitle,
  738.                     1, &pUnk.p, pages.cElems, pages.pElems, lcid, 0, 0);
  739.  
  740.                 CoTaskMemFree(szTitle);
  741.             }
  742.             else
  743.             {
  744.                 hr = OLEOBJ_S_CANNOT_DOVERB_NOW;
  745.             }
  746.             CoTaskMemFree(pages.pElems);
  747.         }
  748.     }
  749.     else
  750.     {
  751.         hr = OLEOBJ_S_CANNOT_DOVERB_NOW;
  752.     }
  753.  
  754.     return hr;
  755. #endif // _WIN32_WCE
  756. }
  757.  
  758. inline HRESULT CComControlBase::InPlaceActivate(LONG iVerb, const RECT* /*prcPosRect*/)
  759. {
  760.     HRESULT hr;
  761.  
  762.     if (m_spClientSite == NULL)
  763.         return S_OK;
  764.  
  765.     CComPtr<IOleInPlaceObject> pIPO;
  766.     ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  767.     ATLASSERT(pIPO != NULL);
  768.  
  769.     if (!m_bNegotiatedWnd)
  770.     {
  771.         if (!m_bWindowOnly)
  772.             // Try for windowless site
  773.             hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSiteWindowless, (void **)&m_spInPlaceSite);
  774.  
  775.         if (m_spInPlaceSite)
  776.         {
  777.             m_bInPlaceSiteEx = TRUE;
  778.             // CanWindowlessActivate returns S_OK or S_FALSE
  779.             if ( m_spInPlaceSite->CanWindowlessActivate() == S_OK )
  780.             {
  781.                 m_bWndLess = TRUE;
  782.                 m_bWasOnceWindowless = TRUE;
  783.             }
  784.             else
  785.             {
  786.                 m_bWndLess = FALSE;
  787.             }
  788.         }
  789.         else
  790.         {
  791.             m_spClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void **)&m_spInPlaceSite);
  792.             if (m_spInPlaceSite)
  793.                 m_bInPlaceSiteEx = TRUE;
  794.             else
  795.                 hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_spInPlaceSite);
  796.         }
  797.     }
  798.  
  799.     ATLASSERT(m_spInPlaceSite);
  800.     if (!m_spInPlaceSite)
  801.         return E_FAIL;
  802.  
  803.     m_bNegotiatedWnd = TRUE;
  804.  
  805.     if (!m_bInPlaceActive)
  806.     {
  807.  
  808.         BOOL bNoRedraw = FALSE;
  809.         if (m_bWndLess)
  810.             m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, ACTIVATE_WINDOWLESS);
  811.         else
  812.         {
  813.             if (m_bInPlaceSiteEx)
  814.                 m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, 0);
  815.             else
  816.             {
  817.                 hr = m_spInPlaceSite->CanInPlaceActivate();
  818.                 // CanInPlaceActivate returns S_FALSE or S_OK
  819.                 if (FAILED(hr))
  820.                     return hr;
  821.                 if ( hr != S_OK )
  822.                 {
  823.                    // CanInPlaceActivate returned S_FALSE.
  824.                    return( E_FAIL );
  825.                 }
  826.                 m_spInPlaceSite->OnInPlaceActivate();
  827.             }
  828.         }
  829.     }
  830.  
  831.     m_bInPlaceActive = TRUE;
  832.  
  833.     // get location in the parent window,
  834.     // as well as some information about the parent
  835.     //
  836.     OLEINPLACEFRAMEINFO frameInfo;
  837.     RECT rcPos, rcClip;
  838.     CComPtr<IOleInPlaceFrame> spInPlaceFrame;
  839.     CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  840.     frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  841.     HWND hwndParent;
  842.     if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK)
  843.     {
  844.         m_spInPlaceSite->GetWindowContext(&spInPlaceFrame,
  845.             &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
  846.  
  847.         if (!m_bWndLess)
  848.         {
  849.             if (m_hWndCD)
  850.             {
  851.                 ShowWindow(m_hWndCD, SW_SHOW);
  852.                 if (!::IsChild(m_hWndCD, ::GetFocus()))
  853.                     ::SetFocus(m_hWndCD);
  854.             }
  855.             else
  856.             {
  857.                 HWND h = CreateControlWindow(hwndParent, rcPos);
  858.                 ATLASSERT(h != NULL);    // will assert if creation failed
  859.                 ATLASSERT(h == m_hWndCD);
  860.                 h;    // avoid unused warning
  861.             }
  862.         }
  863.  
  864.         pIPO->SetObjectRects(&rcPos, &rcClip);
  865.     }
  866.  
  867.     CComPtr<IOleInPlaceActiveObject> spActiveObject;
  868.     ControlQueryInterface(IID_IOleInPlaceActiveObject, (void**)&spActiveObject);
  869.  
  870.     // Gone active by now, take care of UIACTIVATE
  871.     if (DoesVerbUIActivate(iVerb))
  872.     {
  873.         if (!m_bUIActive)
  874.         {
  875.             m_bUIActive = TRUE;
  876.             hr = m_spInPlaceSite->OnUIActivate();
  877.             if (FAILED(hr))
  878.                 return hr;
  879.  
  880.             SetControlFocus(TRUE);
  881.             // set ourselves up in the host.
  882.             //
  883.             if (spActiveObject)
  884.             {
  885.                 if (spInPlaceFrame)
  886.                     spInPlaceFrame->SetActiveObject(spActiveObject, NULL);
  887.                 if (spInPlaceUIWindow)
  888.                     spInPlaceUIWindow->SetActiveObject(spActiveObject, NULL);
  889.             }
  890.  
  891.             if (spInPlaceFrame)
  892.                 spInPlaceFrame->SetBorderSpace(NULL);
  893.             if (spInPlaceUIWindow)
  894.                 spInPlaceUIWindow->SetBorderSpace(NULL);
  895.         }
  896.     }
  897.  
  898.     m_spClientSite->ShowObject();
  899.  
  900.     return S_OK;
  901. }
  902.  
  903. inline HRESULT CComControlBase::SendOnDataChange(DWORD advf)
  904. {
  905.     HRESULT hRes = S_OK;
  906.     if (m_spDataAdviseHolder)
  907.     {
  908.         CComPtr<IDataObject> pdo;
  909.         if (SUCCEEDED(ControlQueryInterface(IID_IDataObject, (void**)&pdo)))
  910.             hRes = m_spDataAdviseHolder->SendOnDataChange(pdo, 0, advf);
  911.     }
  912.     return hRes;
  913. }
  914.  
  915. inline HRESULT CComControlBase::IOleObject_SetClientSite(IOleClientSite *pClientSite)
  916. {
  917.     ATLASSERT(pClientSite == NULL || m_spClientSite == NULL);
  918.     m_spClientSite = pClientSite;
  919.     m_spAmbientDispatch.Release();
  920.     if (m_spClientSite != NULL)
  921.     {
  922.         m_spClientSite->QueryInterface(IID_IDispatch,
  923.             (void**) &m_spAmbientDispatch.p);
  924.     }
  925.     return S_OK;
  926. }
  927.  
  928. inline HRESULT CComControlBase::IOleObject_GetClientSite(IOleClientSite **ppClientSite)
  929. {
  930.     ATLASSERT(ppClientSite);
  931.     if (ppClientSite == NULL)
  932.         return E_POINTER;
  933.  
  934.     *ppClientSite = m_spClientSite;
  935.     if (m_spClientSite != NULL)
  936.         m_spClientSite.p->AddRef();
  937.     return S_OK;
  938. }
  939.  
  940. inline HRESULT CComControlBase::IOleObject_Advise(IAdviseSink *pAdvSink,
  941.     DWORD *pdwConnection)
  942. {
  943.     HRESULT hr = S_OK;
  944.     if (m_spOleAdviseHolder == NULL)
  945.         hr = CreateOleAdviseHolder(&m_spOleAdviseHolder);
  946.     if (SUCCEEDED(hr))
  947.         hr = m_spOleAdviseHolder->Advise(pAdvSink, pdwConnection);
  948.     return hr;
  949. }
  950.  
  951. inline HRESULT CComControlBase::IOleObject_Close(DWORD dwSaveOption)
  952. {
  953.     CComPtr<IOleInPlaceObject> pIPO;
  954.     ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  955.     ATLASSERT(pIPO != NULL);
  956.     if (m_hWndCD)
  957.     {
  958.         if (m_spClientSite)
  959.             m_spClientSite->OnShowWindow(FALSE);
  960.     }
  961.  
  962.     if (m_bInPlaceActive)
  963.     {
  964.         HRESULT hr = pIPO->InPlaceDeactivate();
  965.         if (FAILED(hr))
  966.             return hr;
  967.         ATLASSERT(!m_bInPlaceActive);
  968.     }
  969.     if (m_hWndCD)
  970.     {
  971.         ATLTRACE2(atlTraceControls,2,_T("Destroying Window\n"));
  972.         if (::IsWindow(m_hWndCD))
  973.             DestroyWindow(m_hWndCD);
  974.         m_hWndCD = NULL;
  975.     }
  976.  
  977.     // handle the save flag.
  978.     //
  979.     if ((dwSaveOption == OLECLOSE_SAVEIFDIRTY ||
  980.         dwSaveOption == OLECLOSE_PROMPTSAVE) && m_bRequiresSave)
  981.     {
  982.         if (m_spClientSite)
  983.             m_spClientSite->SaveObject();
  984.         SendOnSave();
  985.     }
  986.  
  987.     m_spInPlaceSite.Release();
  988.     m_bNegotiatedWnd = FALSE;
  989.     m_bWndLess = FALSE;
  990.     m_bInPlaceSiteEx = FALSE;
  991.     m_spAdviseSink.Release();
  992.     return S_OK;
  993. }
  994.  
  995. inline HRESULT CComControlBase::IOleInPlaceObject_InPlaceDeactivate(void)
  996. {
  997.     CComPtr<IOleInPlaceObject> pIPO;
  998.     ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  999.     ATLASSERT(pIPO != NULL);
  1000.  
  1001.     if (!m_bInPlaceActive)
  1002.         return S_OK;
  1003.     pIPO->UIDeactivate();
  1004.  
  1005.     m_bInPlaceActive = FALSE;
  1006.  
  1007.     // if we have a window, tell it to go away.
  1008.     //
  1009.     if (m_hWndCD)
  1010.     {
  1011.         ATLTRACE2(atlTraceControls,2,_T("Destroying Window\n"));
  1012.         if (::IsWindow(m_hWndCD))
  1013.             DestroyWindow(m_hWndCD);
  1014.         m_hWndCD = NULL;
  1015.     }
  1016.  
  1017.     if (m_spInPlaceSite)
  1018.         m_spInPlaceSite->OnInPlaceDeactivate();
  1019.  
  1020.     return S_OK;
  1021. }
  1022.  
  1023. inline HRESULT CComControlBase::IOleInPlaceObject_UIDeactivate(void)
  1024. {
  1025.     // if we're not UIActive, not much to do.
  1026.     //
  1027.     if (!m_bUIActive)
  1028.         return S_OK;
  1029.  
  1030.     m_bUIActive = FALSE;
  1031.  
  1032.     // notify frame windows, if appropriate, that we're no longer ui-active.
  1033.     //
  1034.     CComPtr<IOleInPlaceFrame> spInPlaceFrame;
  1035.     CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  1036.     OLEINPLACEFRAMEINFO frameInfo;
  1037.     frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  1038.     RECT rcPos, rcClip;
  1039.  
  1040.     HWND hwndParent; 
  1041.     // This call to GetWindow is a fix for Delphi
  1042.     if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK)
  1043.     {
  1044.         m_spInPlaceSite->GetWindowContext(&spInPlaceFrame,
  1045.             &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
  1046.         if (spInPlaceUIWindow)
  1047.             spInPlaceUIWindow->SetActiveObject(NULL, NULL);
  1048.         if (spInPlaceFrame)
  1049.             spInPlaceFrame->SetActiveObject(NULL, NULL);
  1050.     }
  1051.     // we don't need to explicitly release the focus here since somebody
  1052.     // else grabbing the focus is what is likely to cause us to get lose it
  1053.     //
  1054.     m_spInPlaceSite->OnUIDeactivate(FALSE);
  1055.  
  1056.     return S_OK;
  1057. }
  1058.  
  1059. inline HRESULT CComControlBase::IOleInPlaceObject_SetObjectRects(LPCRECT prcPos,LPCRECT prcClip)
  1060. {
  1061.     if (prcPos == NULL || prcClip == NULL)
  1062.         return E_POINTER;
  1063.  
  1064.     m_rcPos = *prcPos;
  1065.     if (m_hWndCD)
  1066.     {
  1067.         // the container wants us to clip, so figure out if we really
  1068.         // need to
  1069.         //
  1070. #if defined(_WIN32_WCE)
  1071.         RETAILMSG(1, (TEXT("CComControlBase::IOleInPlaceObject_SetObjectRects: WinCE does not support SetWindowRgn!\r\n")));
  1072. #else // _WIN32_WCE
  1073.         RECT rcIXect;
  1074.         BOOL b = IntersectRect(&rcIXect, prcPos, prcClip);
  1075.         HRGN tempRgn = NULL;
  1076.         if (b && !EqualRect(&rcIXect, prcPos))
  1077.         {
  1078.             OffsetRect(&rcIXect, -(prcPos->left), -(prcPos->top));
  1079.             tempRgn = CreateRectRgnIndirect(&rcIXect);
  1080.         }
  1081.  
  1082.         SetWindowRgn(m_hWndCD, tempRgn, TRUE);
  1083. #endif // _WIN32_WCE
  1084.  
  1085.         // set our control's location, but don't change it's size at all
  1086.         // [people for whom zooming is important should set that up here]
  1087.         //
  1088.         SIZEL size = {prcPos->right - prcPos->left, prcPos->bottom - prcPos->top};
  1089. #if defined(_WIN32_WCE)
  1090.         //NOTE: This is being done because SetWindowPos on CE always
  1091.         //      causes window invalidation, even if the size and position
  1092.         //      remain the same, so to cut down on the blinking, we only
  1093.         //      want to call SetWindowPos when values have actually changed.
  1094.  
  1095.         RECT rcOld;
  1096.  
  1097.         GetWindowRect(m_hWndCD, &rcOld);
  1098.         ::MapWindowPoints(NULL, GetParent(m_hWndCD), (LPPOINT)&rcOld, 2);
  1099.  
  1100.         if (!EqualRect(&rcOld, prcPos)) {
  1101.             SetWindowPos(m_hWndCD, NULL, prcPos->left, prcPos->top,
  1102.                          size.cx, size.cy, SWP_NOZORDER | SWP_NOACTIVATE);
  1103.         }
  1104. #else // _WIN32_WCE
  1105.         SetWindowPos(m_hWndCD, NULL, prcPos->left,
  1106.                      prcPos->top, size.cx, size.cy, SWP_NOZORDER | SWP_NOACTIVATE);
  1107. #endif // _WIN32_WCE
  1108.     }
  1109.  
  1110.     return S_OK;
  1111. }
  1112.  
  1113. inline HRESULT CComControlBase::IOleObject_SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  1114. {
  1115.     if (dwDrawAspect != DVASPECT_CONTENT)
  1116.         return DV_E_DVASPECT;
  1117.     if (psizel == NULL)
  1118.         return E_POINTER;
  1119.  
  1120.     BOOL bSizeMatchesNatural =
  1121.         memcmp(psizel, &m_sizeNatural, sizeof(SIZE)) == 0;
  1122.  
  1123.     if (m_bAutoSize) //object can't do any other size
  1124.         return (bSizeMatchesNatural) ? S_OK : E_FAIL;
  1125.  
  1126.     BOOL bResized = FALSE;
  1127.     if (memcmp(psizel, &m_sizeExtent, sizeof(SIZE)) != 0)
  1128.     {
  1129.         m_sizeExtent = *psizel;
  1130.         bResized = TRUE;
  1131.     }
  1132.     if (m_bResizeNatural && !bSizeMatchesNatural)
  1133.     {
  1134.         m_sizeNatural = *psizel;
  1135.         bResized = TRUE;
  1136.     }
  1137.  
  1138.     if (m_bRecomposeOnResize && bResized)
  1139.     {
  1140.         SendOnDataChange();
  1141.         FireViewChange();
  1142.     }
  1143.     return S_OK;
  1144. }
  1145.  
  1146. inline HRESULT CComControlBase::IViewObject_Draw(DWORD dwDrawAspect, LONG lindex,
  1147.     void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  1148.     LPCRECTL prcBounds, LPCRECTL prcWBounds)
  1149. {
  1150.     ATLTRACE2(atlTraceControls,2,_T("Draw dwDrawAspect=%x lindex=%d ptd=%x hic=%x hdc=%x\n"),
  1151.         dwDrawAspect, lindex, ptd, hicTargetDev, hdcDraw);
  1152. #ifdef _DEBUG
  1153.     if (prcBounds == NULL)
  1154.         ATLTRACE2(atlTraceControls,2,_T("\tprcBounds=NULL\n"));
  1155.     else
  1156.         ATLTRACE2(atlTraceControls,2,_T("\tprcBounds=%d,%d,%d,%d\n"), prcBounds->left,
  1157.             prcBounds->top, prcBounds->right, prcBounds->bottom);
  1158.     if (prcWBounds == NULL)
  1159.         ATLTRACE2(atlTraceControls,2,_T("\tprcWBounds=NULL\n"));
  1160.     else
  1161.         ATLTRACE2(atlTraceControls,2,_T("\tprcWBounds=%d,%d,%d,%d\n"), prcWBounds->left,
  1162.             prcWBounds->top, prcWBounds->right, prcWBounds->bottom);
  1163. #endif
  1164.  
  1165.     if (prcBounds == NULL)
  1166.     {
  1167.         if (!m_bWndLess)
  1168.             return E_INVALIDARG;
  1169.         prcBounds = (RECTL*)&m_rcPos;
  1170.     }
  1171.  
  1172.     // support the aspects required for multi-pass drawing
  1173.     switch (dwDrawAspect)
  1174.     {
  1175.         case DVASPECT_CONTENT:
  1176.         case DVASPECT_OPAQUE:
  1177.         case DVASPECT_TRANSPARENT:
  1178.             break;
  1179.         default:
  1180.             ATLASSERT(FALSE);
  1181.             return DV_E_DVASPECT;
  1182.             break;
  1183.     }
  1184.  
  1185.     // make sure nobody forgets to do this
  1186.     if (ptd == NULL)
  1187.         hicTargetDev = NULL;
  1188.  
  1189.     BOOL bOptimize = FALSE;
  1190.     if (pvAspect && ((DVASPECTINFO *)pvAspect)->cb >= sizeof(DVASPECTINFO))
  1191.         bOptimize = (((DVASPECTINFO *)pvAspect)->dwFlags & DVASPECTINFOFLAG_CANOPTIMIZE);
  1192.  
  1193.     ATL_DRAWINFO di;
  1194.     memset(&di, 0, sizeof(di));
  1195.     di.cbSize = sizeof(di);
  1196.     di.dwDrawAspect = dwDrawAspect;
  1197.     di.lindex = lindex;
  1198.     di.ptd = ptd;
  1199.     di.hicTargetDev = hicTargetDev;
  1200.     di.hdcDraw = hdcDraw;
  1201.     di.prcBounds = prcBounds;
  1202.     di.prcWBounds = prcWBounds;
  1203.     di.bOptimize = bOptimize;
  1204.     return OnDrawAdvanced(di);
  1205. }
  1206.  
  1207. inline HRESULT CComControlBase::IDataObject_GetData(FORMATETC *pformatetcIn,
  1208.     STGMEDIUM *pmedium)
  1209. {
  1210.     if (pmedium == NULL)
  1211.         return E_POINTER;
  1212.     memset(pmedium, 0, sizeof(STGMEDIUM));
  1213.     ATLTRACE2(atlTraceControls,2,_T("Format = %x\n"), pformatetcIn->cfFormat);
  1214.     ATLTRACE2(atlTraceControls,2,_T("TYMED = %x\n"), pformatetcIn->tymed);
  1215.  
  1216.     if ((pformatetcIn->tymed & TYMED_MFPICT) == 0)
  1217.         return DATA_E_FORMATETC;
  1218.  
  1219. #if defined(_WIN32_WCE)
  1220.     RETAILMSG(1, (TEXT("CComControlBase::IDataObject_GetData: WinCE does not support metafiles.\r\n")));
  1221.     return DATA_E_FORMATETC;
  1222. #else // _WIN32_WCE
  1223.     SIZEL sizeMetric, size;
  1224.     if (m_bDrawFromNatural)
  1225.         sizeMetric = m_sizeNatural;
  1226.     else
  1227.         sizeMetric = m_sizeExtent;
  1228.     if (!m_bDrawGetDataInHimetric)
  1229.         AtlHiMetricToPixel(&sizeMetric, &size);
  1230.     else
  1231.         size = sizeMetric;
  1232.     RECTL rectl = {0 ,0, size.cx, size.cy};
  1233.  
  1234.     ATL_DRAWINFO di;
  1235.     memset(&di, 0, sizeof(di));
  1236.     di.cbSize = sizeof(di);
  1237.     di.dwDrawAspect = DVASPECT_CONTENT;
  1238.     di.lindex = -1;
  1239.     di.ptd = NULL;
  1240.     di.hicTargetDev = NULL;
  1241.     di.prcBounds = &rectl;
  1242.     di.prcWBounds = &rectl;
  1243.     di.bOptimize = TRUE; //we do a SaveDC/RestoreDC
  1244.     di.bRectInHimetric = m_bDrawGetDataInHimetric;
  1245.     // create appropriate memory metafile DC
  1246.     di.hdcDraw = CreateMetaFile(NULL);
  1247.  
  1248.     // create attribute DC according to pformatetcIn->ptd
  1249.  
  1250.     SaveDC(di.hdcDraw);
  1251.     SetWindowOrgEx(di.hdcDraw, 0, 0, NULL);
  1252.     SetWindowExtEx(di.hdcDraw, rectl.right, rectl.bottom, NULL);
  1253.     OnDrawAdvanced(di);
  1254.     RestoreDC(di.hdcDraw, -1);
  1255.  
  1256.     HMETAFILE hMF = CloseMetaFile(di.hdcDraw);
  1257.     if (hMF == NULL)
  1258.         return E_UNEXPECTED;
  1259.  
  1260.     HGLOBAL hMem=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(METAFILEPICT));
  1261.  
  1262.     if (NULL==hMem)
  1263.     {
  1264.         DeleteMetaFile(hMF);
  1265.         return ResultFromScode(STG_E_MEDIUMFULL);
  1266.     }
  1267.  
  1268.     LPMETAFILEPICT pMF=(LPMETAFILEPICT)GlobalLock(hMem);
  1269.     pMF->hMF=hMF;
  1270.     pMF->mm=MM_ANISOTROPIC;
  1271.     pMF->xExt=sizeMetric.cx;
  1272.     pMF->yExt=sizeMetric.cy;
  1273.     GlobalUnlock(hMem);
  1274.  
  1275.     pmedium->tymed = TYMED_MFPICT;
  1276.     pmedium->hGlobal = hMem;
  1277.     pmedium->pUnkForRelease = NULL;
  1278.  
  1279.     return S_OK;
  1280. #endif // _WIN32_WCE
  1281. }
  1282.  
  1283. inline HRESULT CComControlBase::FireViewChange()
  1284. {
  1285.     if (m_bInPlaceActive)
  1286.     {
  1287.         // Active
  1288.         if (m_hWndCD != NULL)
  1289.             ::InvalidateRect(m_hWndCD, NULL, TRUE); // Window based
  1290.         else if (m_spInPlaceSite != NULL)
  1291.             m_spInPlaceSite->InvalidateRect(NULL, TRUE); // Windowless
  1292.     }
  1293.     else // Inactive
  1294.         SendOnViewChange(DVASPECT_CONTENT);
  1295.     return S_OK;
  1296. }
  1297.  
  1298. inline void CComControlBase::GetZoomInfo(ATL_DRAWINFO& di)
  1299. {
  1300.     const RECTL& rcPos = *di.prcBounds;
  1301.     SIZEL sizeDen;
  1302.     if (m_bDrawFromNatural)
  1303.         sizeDen = m_sizeNatural;
  1304.     else
  1305.         sizeDen = m_sizeExtent;
  1306.     if (!di.bRectInHimetric)
  1307.         AtlHiMetricToPixel(&sizeDen, &sizeDen);
  1308.     SIZEL sizeNum = {rcPos.right-rcPos.left, rcPos.bottom-rcPos.top};
  1309.     di.ZoomNum.cx = sizeNum.cx;
  1310.     di.ZoomNum.cy = sizeNum.cy;
  1311.     di.ZoomDen.cx = sizeDen.cx;
  1312.     di.ZoomDen.cy = sizeDen.cy;
  1313.     if (sizeDen.cx == 0 || sizeDen.cy == 0 ||
  1314.         sizeNum.cx == 0 || sizeNum.cy == 0)
  1315.     {
  1316.         di.ZoomNum.cx = di.ZoomNum.cy = di.ZoomDen.cx = di.ZoomDen.cy = 1;
  1317.         di.bZoomed = FALSE;
  1318.     }
  1319.     else if (sizeNum.cx != sizeDen.cx || sizeNum.cy != sizeDen.cy)
  1320.         di.bZoomed = TRUE;
  1321.     else
  1322.         di.bZoomed = FALSE;
  1323. }
  1324.  
  1325. inline HRESULT CComControlBase::OnDrawAdvanced(ATL_DRAWINFO& di)
  1326. {
  1327.     BOOL bDeleteDC = FALSE;
  1328.     if (di.hicTargetDev == NULL)
  1329.     {
  1330.         di.hicTargetDev = AtlCreateTargetDC(di.hdcDraw, di.ptd);
  1331.         bDeleteDC = (di.hicTargetDev != di.hdcDraw);
  1332.     }
  1333.     RECTL rectBoundsDP = *di.prcBounds;
  1334.     BOOL bMetafile = WCE_IF(FALSE, (GetDeviceCaps(di.hdcDraw, TECHNOLOGY) == DT_METAFILE));
  1335.     if (!bMetafile)
  1336.     {
  1337. #if defined(_WIN32_WCE)
  1338. // WinCE: No GDI transform API's
  1339.         SaveDC(di.hdcDraw);
  1340. #else // _WIN32_WCE
  1341.         ::LPtoDP(di.hicTargetDev, (LPPOINT)&rectBoundsDP, 2);
  1342.         SaveDC(di.hdcDraw);
  1343.         SetMapMode(di.hdcDraw, MM_TEXT);
  1344.         SetWindowOrgEx(di.hdcDraw, 0, 0, NULL);
  1345.         SetViewportOrgEx(di.hdcDraw, 0, 0, NULL);
  1346. #endif // _WIN32_WCE
  1347.         di.bOptimize = TRUE; //since we save the DC we can do this
  1348.     }
  1349.     di.prcBounds = &rectBoundsDP;
  1350.     GetZoomInfo(di);
  1351.  
  1352.     HRESULT hRes = OnDraw(di);
  1353.     if (bDeleteDC)
  1354.         ::DeleteDC(di.hicTargetDev);
  1355.     if (!bMetafile)
  1356.         RestoreDC(di.hdcDraw, -1);
  1357.     return hRes;
  1358. }
  1359.  
  1360. inline LRESULT CComControlBase::OnPaint(UINT /* uMsg */, WPARAM wParam,
  1361.     LPARAM /* lParam */, BOOL& /* lResult */)
  1362. {
  1363.     RECT rc;
  1364.     PAINTSTRUCT ps;
  1365.  
  1366.     HDC hdc = (wParam != NULL) ? (HDC)wParam : ::BeginPaint(m_hWndCD, &ps);
  1367.     if (hdc == NULL)
  1368.         return 0;
  1369.     ::GetClientRect(m_hWndCD, &rc);
  1370.  
  1371.     ATL_DRAWINFO di;
  1372.     memset(&di, 0, sizeof(di));
  1373.     di.cbSize = sizeof(di);
  1374.     di.dwDrawAspect = DVASPECT_CONTENT;
  1375.     di.lindex = -1;
  1376.     di.hdcDraw = hdc;
  1377.     di.prcBounds = (LPCRECTL)&rc;
  1378.  
  1379.     OnDrawAdvanced(di);
  1380.     if (wParam == NULL)
  1381.         ::EndPaint(m_hWndCD, &ps);
  1382.     return 0;
  1383. }
  1384.  
  1385. template <class T, class WinBase =  CWindowImpl< T > >
  1386. class ATL_NO_VTABLE CComControl :  public CComControlBase, public WinBase
  1387. {
  1388. public:
  1389.     CComControl() : CComControlBase(m_hWnd) {}
  1390.     HRESULT FireOnRequestEdit(DISPID dispID)
  1391.     {
  1392.         T* pT = static_cast<T*>(this);
  1393.         return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID);
  1394.     }
  1395.     HRESULT FireOnChanged(DISPID dispID)
  1396.     {
  1397.         T* pT = static_cast<T*>(this);
  1398.         return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID);
  1399.     }
  1400.     virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
  1401.     {
  1402.         T* pT = static_cast<T*>(this);
  1403.         return pT->_InternalQueryInterface(iid, ppv);
  1404.     }
  1405.     virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
  1406.     {
  1407.         T* pT = static_cast<T*>(this);
  1408.         return pT->Create(hWndParent, rcPos);
  1409.     }
  1410.  
  1411.     typedef CComControl< T, WinBase >    thisClass;
  1412.     BEGIN_MSG_MAP(thisClass)
  1413.         MESSAGE_HANDLER(WM_PAINT, CComControlBase::OnPaint)
  1414.         MESSAGE_HANDLER(WM_SETFOCUS, CComControlBase::OnSetFocus)
  1415.         MESSAGE_HANDLER(WM_KILLFOCUS, CComControlBase::OnKillFocus)
  1416.         WCE_DEL MESSAGE_HANDLER(WM_MOUSEACTIVATE, CComControlBase::OnMouseActivate)
  1417.     END_MSG_MAP()
  1418. };
  1419.  
  1420. //////////////////////////////////////////////////////////////////////////////
  1421. // CComCompositeControl
  1422.  
  1423. #ifndef _ATL_NO_HOSTING
  1424. template <class T>
  1425. class CComCompositeControl : public CComControl< T, CAxDialogImpl< T > >
  1426. {
  1427. public:
  1428.     CComCompositeControl()
  1429.     {
  1430.         m_hbrBackground = NULL;
  1431.     }
  1432.     ~CComCompositeControl()
  1433.     {
  1434.         DeleteObject(m_hbrBackground);
  1435.     }
  1436.     HRESULT AdviseSinkMap(bool bAdvise)
  1437.     {
  1438.         if(!bAdvise && m_hWnd == NULL)
  1439.         {
  1440.             // window is gone, controls are already unadvised
  1441.             ATLTRACE2(atlTraceControls, 1, _T("CComCompositeControl::AdviseSinkMap called after the window was destroyed\n"));
  1442.             return S_OK;
  1443.         }
  1444.         T* pT = static_cast<T*>(this);
  1445.         return AtlAdviseSinkMap(pT, bAdvise);
  1446.     }
  1447.     HBRUSH m_hbrBackground;
  1448.     HRESULT SetBackgroundColorFromAmbient()
  1449.     {
  1450.         if (m_hbrBackground != NULL)
  1451.         {
  1452.             DeleteObject(m_hbrBackground);
  1453.             m_hbrBackground = NULL;
  1454.         }
  1455.         OLE_COLOR clr;
  1456.         HRESULT hr = GetAmbientBackColor(clr);
  1457.         if (SUCCEEDED(hr))
  1458.         {
  1459.             COLORREF rgb;
  1460. #if defined(_WIN32_WCE)
  1461.         if(clr & 0x80000000L) 
  1462.             rgb = GetSysColor((clr & 0x000000FFL) | 0x40000000L);
  1463.         else 
  1464.             rgb = (COLORREF)(clr & 0x00FFFFFFL);
  1465. #else // _WIN32_WCE
  1466.             ::OleTranslateColor(clr, NULL, &rgb);
  1467. #endif // _WIN32_WCE            
  1468.             m_hbrBackground = ::CreateSolidBrush(rgb);
  1469. #if defined(_WIN32_WCE)
  1470.             HWND hWnd = ::GetWindow(m_hWnd, GW_CHILD);
  1471.             if(hWnd)
  1472.             {
  1473.                 hWnd = ::GetWindow(hWnd, GW_HWNDFIRST);
  1474.                 while(hWnd)
  1475.                 {
  1476.                     BackgroundColorEnumProc(hWnd, (LPARAM)clr);
  1477.                     hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  1478.                 }
  1479.             }
  1480. #else // _WIN32_WCE
  1481.             EnumChildWindows(m_hWnd, (WNDENUMPROC)BackgroundColorEnumProc, (LPARAM) clr);
  1482. #endif // _WIN32_WCE
  1483.         }
  1484.         return hr;
  1485.     }
  1486.     static BOOL CALLBACK BackgroundColorEnumProc(HWND hwnd, LPARAM l)
  1487.     {
  1488.         CAxWindow wnd(hwnd);
  1489.         CComPtr<IAxWinAmbientDispatch> spDispatch;
  1490.         wnd.QueryHost(&spDispatch);
  1491.         if (spDispatch != NULL)
  1492.             spDispatch->put_BackColor((OLE_COLOR)l);
  1493.         return TRUE;
  1494.     }
  1495.     LRESULT OnDialogColor(UINT, WPARAM w, LPARAM, BOOL&)
  1496.     {
  1497.         HDC dc = (HDC) w;
  1498.         LOGBRUSH lb;
  1499.         ::GetObject(m_hbrBackground, sizeof(lb), (void*)&lb);
  1500.         ::SetBkColor(dc, lb.lbColor);
  1501.         return (LRESULT)m_hbrBackground;
  1502.     }
  1503.     HWND Create(HWND hWndParent, RECT& /*rcPos*/, LPARAM dwInitParam = NULL)
  1504.     {
  1505.         CComControl< T, CAxDialogImpl< T > >::Create(hWndParent, dwInitParam);
  1506.         SetBackgroundColorFromAmbient();
  1507.         if (m_hWnd != NULL)
  1508.             ShowWindow(SW_SHOWNOACTIVATE);
  1509.         return m_hWnd;
  1510.     }
  1511.     BOOL CalcExtent(SIZE& size)
  1512.     {
  1513.         HINSTANCE hInstance = _Module.GetResourceInstance();
  1514.         LPCTSTR lpTemplateName = MAKEINTRESOURCE(T::IDD);
  1515.         HRSRC hDlgTempl = FindResource(hInstance, lpTemplateName, RT_DIALOG);
  1516.         if (hDlgTempl == NULL)
  1517.             return FALSE;
  1518.         HGLOBAL hResource = LoadResource(hInstance, hDlgTempl);
  1519.         DLGTEMPLATE* pDlgTempl = (DLGTEMPLATE*)LockResource(hResource);
  1520.         if (pDlgTempl == NULL)
  1521.             return FALSE;
  1522.         AtlGetDialogSize(pDlgTempl, &size);
  1523.         AtlPixelToHiMetric(&size, &size);
  1524.         return TRUE;
  1525.     }
  1526. //Implementation
  1527.     BOOL PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet)
  1528.     {
  1529.         hRet = S_OK;
  1530.         if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
  1531.            (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
  1532.             return FALSE;
  1533.         // find a direct child of the dialog from the window that has focus
  1534.         HWND hWndCtl = ::GetFocus();
  1535.         if (IsChild(hWndCtl) && ::GetParent(hWndCtl) != m_hWnd)
  1536.         {
  1537.             do
  1538.             {
  1539.                 hWndCtl = ::GetParent(hWndCtl);
  1540.             }
  1541.             while (::GetParent(hWndCtl) != m_hWnd);
  1542.         }
  1543.         // give controls a chance to translate this message
  1544.         if (::SendMessage(hWndCtl, WM_FORWARDMSG, 0, (LPARAM)pMsg) == 1)
  1545.             return TRUE;
  1546.  
  1547.         // special handling for keyboard messages
  1548.         DWORD dwDlgCode = ::SendMessage(pMsg->hwnd, WM_GETDLGCODE, 0, 0L);
  1549.         switch(pMsg->message)
  1550.         {
  1551.         case WM_CHAR:
  1552.             if(dwDlgCode == 0)    // no dlgcode, possibly an ActiveX control
  1553.                 return FALSE;    // let the container process this
  1554.             break;
  1555.         case WM_KEYDOWN:
  1556.             switch(LOWORD(pMsg->wParam))
  1557.             {
  1558.             case VK_TAB:
  1559.                 // prevent tab from looping inside of our dialog
  1560.                 if((dwDlgCode & DLGC_WANTTAB) == 0)
  1561.                 {
  1562.                     HWND hWndFirstOrLast = ::GetWindow(m_hWnd, GW_CHILD);
  1563.                     if (::GetKeyState(VK_SHIFT) >= 0)  // not pressed
  1564.                         hWndFirstOrLast = GetNextDlgTabItem(hWndFirstOrLast, TRUE);
  1565.                     if (hWndFirstOrLast == hWndCtl)
  1566.                         return FALSE;
  1567.                 }
  1568.                 break;
  1569.             case VK_LEFT:
  1570.             case VK_UP:
  1571.             case VK_RIGHT:
  1572.             case VK_DOWN:
  1573.                 // prevent arrows from looping inside of our dialog
  1574.                 if((dwDlgCode & DLGC_WANTARROWS) == 0)
  1575.                 {
  1576.                     HWND hWndFirstOrLast = ::GetWindow(m_hWnd, GW_CHILD);
  1577.                     if (pMsg->wParam == VK_RIGHT || pMsg->wParam == VK_DOWN)    // going forward
  1578.                         hWndFirstOrLast = GetNextDlgTabItem(hWndFirstOrLast, TRUE);
  1579.                     if (hWndFirstOrLast == hWndCtl)
  1580.                         return FALSE;
  1581.                 }
  1582.                 break;
  1583.             case VK_EXECUTE:
  1584.             case VK_RETURN:
  1585.             case VK_ESCAPE:
  1586.             case VK_CANCEL:
  1587.                 // we don't want to handle these, let the container do it
  1588.                 return FALSE;
  1589.             }
  1590.             break;
  1591.         }
  1592.  
  1593.         return IsDialogMessage(pMsg);
  1594.     }
  1595.     HRESULT IOleInPlaceObject_InPlaceDeactivate(void)
  1596.     {
  1597.         AdviseSinkMap(false); //unadvise
  1598.         return CComControl<T, CAxDialogImpl<T> >::IOleInPlaceObject_InPlaceDeactivate();
  1599.     }
  1600.     virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
  1601.     {
  1602.         T* pT = static_cast<T*>(this);
  1603.         HWND h = pT->Create(hWndParent, rcPos);
  1604.         if (h != NULL)
  1605.             AdviseSinkMap(true);
  1606.         return h;
  1607.     }
  1608.     virtual HRESULT OnDraw(ATL_DRAWINFO& di)
  1609.     {
  1610.         if(!m_bInPlaceActive)
  1611.         {
  1612.             HPEN hPen = (HPEN)::GetStockObject(BLACK_PEN);
  1613.             HBRUSH hBrush = (HBRUSH)::GetStockObject(GRAY_BRUSH);
  1614.             ::SelectObject(di.hdcDraw, hPen);
  1615.             ::SelectObject(di.hdcDraw, hBrush);
  1616.             ::Rectangle(di.hdcDraw, di.prcBounds->left, di.prcBounds->top, di.prcBounds->right, di.prcBounds->bottom);
  1617.             ::SetTextColor(di.hdcDraw, ::GetSysColor(COLOR_WINDOWTEXT));
  1618.             ::SetBkMode(di.hdcDraw, TRANSPARENT);
  1619.             ::DrawText(di.hdcDraw, _T("ATL Composite Control"), -1, (LPRECT)di.prcBounds, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
  1620.         }
  1621.         return S_OK;
  1622.     }
  1623.  
  1624.     typedef CComControl< T, CAxDialogImpl< T > >    baseClass;
  1625.     BEGIN_MSG_MAP(CComCompositeControl< T >)
  1626.         MESSAGE_HANDLER(WM_CTLCOLORDLG, OnDialogColor)
  1627.         MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnDialogColor)
  1628.         MESSAGE_HANDLER(WM_SETFOCUS, baseClass::OnSetFocus)
  1629.         MESSAGE_HANDLER(WM_KILLFOCUS, baseClass::OnKillFocus)
  1630.         WCE_DEL MESSAGE_HANDLER(WM_MOUSEACTIVATE, baseClass::OnMouseActivate)
  1631.     END_MSG_MAP()
  1632.  
  1633.     BEGIN_SINK_MAP(T)
  1634.     END_SINK_MAP()
  1635. };
  1636. #endif //_ATL_NO_HOSTING
  1637.  
  1638. // Forward declarations
  1639. //
  1640. template <class T> class IPersistStorageImpl;
  1641. template <class T> class IPersistPropertyBagImpl;
  1642.  
  1643. template <class T> class IOleControlImpl;
  1644. template <class T> class IRunnableObjectImpl;
  1645. template <class T> class IQuickActivateImpl;
  1646. template <class T> class IOleObjectImpl;
  1647. template <class T> class IPropertyPageImpl;
  1648. template <class T> class IPropertyPage2Impl;
  1649. template <class T> class IPerPropertyBrowsingImpl;
  1650. template <class T> class IViewObjectExImpl;
  1651. template <class T> class IOleWindowImpl;
  1652. template <class T> class IPointerInactiveImpl;
  1653. template <class T, class CDV> class IPropertyNotifySinkCP;
  1654. #if !defined(_WIN32_WCE)
  1655. template <class T> class IBindStatusCallbackImpl;
  1656. template <class T> class CBindStatusCallback;
  1657. #endif // _WIN32_WCE
  1658.  
  1659.  
  1660. //////////////////////////////////////////////////////////////////////////////
  1661. // IOleControlImpl
  1662. template <class T>
  1663. class ATL_NO_VTABLE IOleControlImpl : public IOleControl
  1664. {
  1665. public:
  1666.     STDMETHOD(GetControlInfo)(LPCONTROLINFO /* pCI */)
  1667.     {
  1668.         ATLTRACENOTIMPL(_T("IOleControlImpl::GetControlInfo"));
  1669.     }
  1670.     STDMETHOD(OnMnemonic)(LPMSG /* pMsg */)
  1671.     {
  1672.         ATLTRACENOTIMPL(_T("IOleControlImpl::OnMnemonic"));
  1673.     }
  1674.     STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
  1675.     {
  1676.         dispid;
  1677.         ATLTRACE2(atlTraceControls,2,_T("IOleControlImpl::OnAmbientPropertyChange\n"));
  1678.         ATLTRACE2(atlTraceControls,2,_T(" -- DISPID = %d (%d)\n"), dispid);
  1679.         return S_OK;
  1680.     }
  1681.     STDMETHOD(FreezeEvents)(BOOL bFreeze)
  1682.     {
  1683.         T* pT = static_cast<T*>(this);
  1684.         ATLTRACE2(atlTraceControls,2,_T("IOleControlImpl::FreezeEvents\n"));
  1685.         if (bFreeze)
  1686.             pT->m_nFreezeEvents++;
  1687.         else
  1688.             pT->m_nFreezeEvents--;
  1689.         return S_OK;
  1690.     }
  1691. };
  1692.  
  1693.  
  1694. //////////////////////////////////////////////////////////////////////////////
  1695. // IQuickActivateImpl
  1696. template <class T>
  1697. class ATL_NO_VTABLE IQuickActivateImpl : public IQuickActivate
  1698. {
  1699. public:
  1700.     STDMETHOD(QuickActivate)(QACONTAINER *pQACont, QACONTROL *pQACtrl)
  1701.     {
  1702.         T* pT = static_cast<T*>(this);
  1703.         ATLTRACE2(atlTraceControls,2,_T("IQuickActivateImpl::QuickActivate\n"));
  1704.         return pT->IQuickActivate_QuickActivate(pQACont, pQACtrl);
  1705.     }
  1706.     STDMETHOD(SetContentExtent)(LPSIZEL pSize)
  1707.     {
  1708.         T* pT = static_cast<T*>(this);
  1709.         ATLTRACE2(atlTraceControls,2,_T("IQuickActivateImpl::SetContentExtent\n"));
  1710.         return pT->IOleObjectImpl<T>::SetExtent(DVASPECT_CONTENT, pSize);
  1711.     }
  1712.     STDMETHOD(GetContentExtent)(LPSIZEL pSize)
  1713.     {
  1714.         T* pT = static_cast<T*>(this);
  1715.         ATLTRACE2(atlTraceControls,2,_T("IQuickActivateImpl::GetContentExtent\n"));
  1716.         return pT->IOleObjectImpl<T>::GetExtent(DVASPECT_CONTENT, pSize);
  1717.     }
  1718. };
  1719.  
  1720.  
  1721. //////////////////////////////////////////////////////////////////////////////
  1722. // IOleObjectImpl
  1723. template <class T>
  1724. class ATL_NO_VTABLE IOleObjectImpl : public IOleObject
  1725. {
  1726. public:
  1727.     STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)
  1728.     {
  1729.         T* pT = static_cast<T*>(this);
  1730.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::SetClientSite\n"));
  1731.         return pT->IOleObject_SetClientSite(pClientSite);
  1732.     }
  1733.     STDMETHOD(GetClientSite)(IOleClientSite **ppClientSite)
  1734.     {
  1735.         T* pT = static_cast<T*>(this);
  1736.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetClientSite\n"));
  1737.         return pT->IOleObject_GetClientSite(ppClientSite);
  1738.     }
  1739.     STDMETHOD(SetHostNames)(LPCOLESTR /* szContainerApp */, LPCOLESTR /* szContainerObj */)
  1740.     {
  1741.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::SetHostNames\n"));
  1742.         return S_OK;
  1743.     }
  1744.     STDMETHOD(Close)(DWORD dwSaveOption)
  1745.     {
  1746.         T* pT = static_cast<T*>(this);
  1747.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::Close\n"));
  1748.         return pT->IOleObject_Close(dwSaveOption);
  1749.     }
  1750.     STDMETHOD(SetMoniker)(DWORD /* dwWhichMoniker */, IMoniker* /* pmk */)
  1751.     {
  1752.         ATLTRACENOTIMPL(_T("IOleObjectImpl::SetMoniker"));
  1753.     }
  1754.     STDMETHOD(GetMoniker)(DWORD /* dwAssign */, DWORD /* dwWhichMoniker */, IMoniker** /* ppmk */)
  1755.     {
  1756.         ATLTRACENOTIMPL(_T("IOleObjectImpl::GetMoniker"));
  1757.     }
  1758.     STDMETHOD(InitFromData)(IDataObject* /* pDataObject */, BOOL /* fCreation */, DWORD /* dwReserved */)
  1759.     {
  1760.         ATLTRACENOTIMPL(_T("IOleObjectImpl::InitFromData"));
  1761.     }
  1762.     STDMETHOD(GetClipboardData)(DWORD /* dwReserved */, IDataObject** /* ppDataObject */)
  1763.     {
  1764.         ATLTRACENOTIMPL(_T("IOleObjectImpl::GetClipboardData"));
  1765.     }
  1766.  
  1767.     // Helpers for DoVerb - Over-rideable in user class
  1768.     HRESULT DoVerbPrimary(LPCRECT prcPosRect, HWND hwndParent)
  1769.     {
  1770.         T* pT = static_cast<T*>(this);
  1771.         BOOL bDesignMode = FALSE;
  1772.         CComVariant var;
  1773.         // if container doesn't support this property
  1774.         // don't allow design mode
  1775.         HRESULT hRes = pT->GetAmbientProperty(DISPID_AMBIENT_USERMODE, var);
  1776.         if (SUCCEEDED(hRes) && var.vt == VT_BOOL && !var.boolVal)
  1777.             bDesignMode = TRUE;
  1778.         if (bDesignMode)
  1779.             return pT->DoVerbProperties(prcPosRect, hwndParent);
  1780.         else
  1781.             return pT->DoVerbInPlaceActivate(prcPosRect, hwndParent);
  1782.     }
  1783.     HRESULT DoVerbShow(LPCRECT prcPosRect, HWND /* hwndParent */)
  1784.     {
  1785.         T* pT = static_cast<T*>(this);
  1786.         HRESULT hr;
  1787.         hr = pT->OnPreVerbShow();
  1788.         if (SUCCEEDED(hr))
  1789.         {
  1790.             hr = pT->InPlaceActivate(OLEIVERB_SHOW, prcPosRect);
  1791.             if (SUCCEEDED(hr))
  1792.                 hr = pT->OnPostVerbShow();
  1793.         }
  1794.         return hr;
  1795.     }
  1796.     HRESULT DoVerbInPlaceActivate(LPCRECT prcPosRect, HWND /* hwndParent */)
  1797.     {
  1798.         T* pT = static_cast<T*>(this);
  1799.         HRESULT hr;
  1800.         hr = pT->OnPreVerbInPlaceActivate();
  1801.         if (SUCCEEDED(hr))
  1802.         {
  1803.             hr = pT->InPlaceActivate(OLEIVERB_INPLACEACTIVATE, prcPosRect);
  1804.             if (SUCCEEDED(hr))
  1805.                 hr = pT->OnPostVerbInPlaceActivate();
  1806.             if (SUCCEEDED(hr))
  1807.                 pT->FireViewChange();
  1808.         }
  1809.         return hr;
  1810.     }
  1811.     HRESULT DoVerbUIActivate(LPCRECT prcPosRect, HWND /* hwndParent */)
  1812.     {
  1813.         T* pT = static_cast<T*>(this);
  1814.         HRESULT hr = S_OK;
  1815.         if (!pT->m_bUIActive)
  1816.         {
  1817.             hr = pT->OnPreVerbUIActivate();
  1818.             if (SUCCEEDED(hr))
  1819.             {
  1820.                 hr = pT->InPlaceActivate(OLEIVERB_UIACTIVATE, prcPosRect);
  1821.                 if (SUCCEEDED(hr))
  1822.                     hr = pT->OnPostVerbUIActivate();
  1823.             }
  1824.         }
  1825.         return hr;
  1826.     }
  1827.     HRESULT DoVerbHide(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  1828.     {
  1829.         T* pT = static_cast<T*>(this);
  1830.         HRESULT hr;
  1831.         hr = pT->OnPreVerbHide();
  1832.         if (SUCCEEDED(hr))
  1833.         {
  1834.             pT->UIDeactivate();
  1835.             if (pT->m_hWnd)
  1836.                 pT->ShowWindow(SW_HIDE);
  1837.             hr = pT->OnPostVerbHide();
  1838.         }
  1839.         return hr;
  1840.     }
  1841.     HRESULT DoVerbOpen(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  1842.     {
  1843.         T* pT = static_cast<T*>(this);
  1844.         HRESULT hr;
  1845.         hr = pT->OnPreVerbOpen();
  1846.         if (SUCCEEDED(hr))
  1847.             hr = pT->OnPostVerbOpen();
  1848.         return hr;
  1849.     }
  1850.     HRESULT DoVerbDiscardUndo(LPCRECT /* prcPosRect */, HWND /* hwndParent */)
  1851.     {
  1852.         T* pT = static_cast<T*>(this);
  1853.         HRESULT hr;
  1854.         hr = pT->OnPreVerbDiscardUndo();
  1855.         if (SUCCEEDED(hr))
  1856.             hr = pT->OnPostVerbDiscardUndo();
  1857.         return hr;
  1858.     }
  1859.     STDMETHOD(DoVerb)(LONG iVerb, LPMSG /* pMsg */, IOleClientSite* /* pActiveSite */, LONG /* lindex */,
  1860.                                      HWND hwndParent, LPCRECT lprcPosRect)
  1861.     {
  1862.         T* pT = static_cast<T*>(this);
  1863.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::DoVerb(%d)\n"), iVerb);
  1864.         ATLASSERT(pT->m_spClientSite);
  1865.  
  1866.         HRESULT hr = E_NOTIMPL;
  1867.         switch (iVerb)
  1868.         {
  1869.         case OLEIVERB_PRIMARY:
  1870.             hr = pT->DoVerbPrimary(lprcPosRect, hwndParent);
  1871.             break;
  1872.         case OLEIVERB_SHOW:
  1873.             hr = pT->DoVerbShow(lprcPosRect, hwndParent);
  1874.             break;
  1875.         case OLEIVERB_INPLACEACTIVATE:
  1876.             hr = pT->DoVerbInPlaceActivate(lprcPosRect, hwndParent);
  1877.             break;
  1878.         case OLEIVERB_UIACTIVATE:
  1879.             hr = pT->DoVerbUIActivate(lprcPosRect, hwndParent);
  1880.             break;
  1881.         case OLEIVERB_HIDE:
  1882.             hr = pT->DoVerbHide(lprcPosRect, hwndParent);
  1883.             break;
  1884.         case OLEIVERB_OPEN:
  1885.             hr = pT->DoVerbOpen(lprcPosRect, hwndParent);
  1886.             break;
  1887.         case OLEIVERB_DISCARDUNDOSTATE:
  1888.             hr = pT->DoVerbDiscardUndo(lprcPosRect, hwndParent);
  1889.             break;
  1890.         case OLEIVERB_PROPERTIES:
  1891.             hr = pT->DoVerbProperties(lprcPosRect, hwndParent);
  1892.         }
  1893.         return hr;
  1894.     }
  1895.     STDMETHOD(EnumVerbs)(IEnumOLEVERB **ppEnumOleVerb)
  1896.     {
  1897. #if defined(_WIN32_WCE)
  1898. // WinCE: No OleRegEnumVerbs
  1899.         RETAILMSG(1, (TEXT("IOleObjectImpl::EnumVerbs: Not implemented\r\n")));
  1900.         return E_NOTIMPL;
  1901. #else // _WIN32_WCE
  1902.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::EnumVerbs\n"));
  1903.         ATLASSERT(ppEnumOleVerb);
  1904.         if (!ppEnumOleVerb)
  1905.             return E_POINTER;
  1906.         return OleRegEnumVerbs(T::GetObjectCLSID(), ppEnumOleVerb);
  1907. #endif // _WIN32_WCE
  1908.     }
  1909.     STDMETHOD(Update)(void)
  1910.     {
  1911.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::Update\n"));
  1912.         return S_OK;
  1913.     }
  1914.     STDMETHOD(IsUpToDate)(void)
  1915.     {
  1916.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::IsUpToDate\n"));
  1917.         return S_OK;
  1918.     }
  1919.     STDMETHOD(GetUserClassID)(CLSID *pClsid)
  1920.     {
  1921.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetUserClassID\n"));
  1922.         ATLASSERT(pClsid);
  1923.         if (!pClsid)
  1924.             return E_POINTER;
  1925.         *pClsid = T::GetObjectCLSID();
  1926.         return S_OK;
  1927.     }
  1928.     STDMETHOD(GetUserType)(DWORD dwFormOfType, LPOLESTR *pszUserType)
  1929.     {
  1930. #if defined(_WIN32_WCE)
  1931. // WinCE: No OleRegGetUserType 
  1932.         RETAILMSG(1, (TEXT("IOleObjectImpl::GetUserType: Not implemented\r\n")));
  1933.         return E_NOTIMPL;
  1934. #else // _WIN32_WCE
  1935.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetUserType\n"));
  1936.         return OleRegGetUserType(T::GetObjectCLSID(), dwFormOfType, pszUserType);
  1937. #endif // _WIN32_WCE
  1938.     }
  1939.     STDMETHOD(SetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
  1940.     {
  1941.         T* pT = static_cast<T*>(this);
  1942.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::SetExtent\n"));
  1943.         return pT->IOleObject_SetExtent(dwDrawAspect, psizel);
  1944.     }
  1945.     STDMETHOD(GetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
  1946.     {
  1947.         T* pT = static_cast<T*>(this);
  1948.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetExtent\n"));
  1949.         if (dwDrawAspect != DVASPECT_CONTENT)
  1950.             return E_FAIL;
  1951.         if (psizel == NULL)
  1952.             return E_POINTER;
  1953.         *psizel = pT->m_sizeExtent;
  1954.         return S_OK;
  1955.     }
  1956.     STDMETHOD(Advise)(IAdviseSink *pAdvSink, DWORD *pdwConnection)
  1957.     {
  1958.         T* pT = static_cast<T*>(this);
  1959.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::Advise\n"));
  1960.         return pT->IOleObject_Advise(pAdvSink, pdwConnection);
  1961.     }
  1962.     STDMETHOD(Unadvise)(DWORD dwConnection)
  1963.     {
  1964.         T* pT = static_cast<T*>(this);
  1965.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::Unadvise\n"));
  1966.         HRESULT hRes = E_FAIL;
  1967.         if (pT->m_spOleAdviseHolder != NULL)
  1968.             hRes = pT->m_spOleAdviseHolder->Unadvise(dwConnection);
  1969.         return hRes;
  1970.     }
  1971.     STDMETHOD(EnumAdvise)(IEnumSTATDATA **ppenumAdvise)
  1972.     {
  1973.         T* pT = static_cast<T*>(this);
  1974.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::EnumAdvise\n"));
  1975.         HRESULT hRes = E_FAIL;
  1976.         if (pT->m_spOleAdviseHolder != NULL)
  1977.             hRes = pT->m_spOleAdviseHolder->EnumAdvise(ppenumAdvise);
  1978.         return hRes;
  1979.     }
  1980.     STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD *pdwStatus)
  1981.     {
  1982. #if defined(_WIN32_WCE)
  1983. // WinCE: No OleRegGetMiscStatus
  1984.         RETAILMSG(1, (TEXT("IOleObjectImpl::GetMiscStatus: Not implemented\r\n")));
  1985.         return E_NOTIMPL;
  1986. #else // _WIN32_WCE
  1987.         ATLTRACE2(atlTraceControls,2,_T("IOleObjectImpl::GetMiscStatus\n"));
  1988.         return OleRegGetMiscStatus(T::GetObjectCLSID(), dwAspect, pdwStatus);
  1989. #endif // _WIN32_WCE
  1990.     }
  1991.     STDMETHOD(SetColorScheme)(LOGPALETTE* /* pLogpal */)
  1992.     {
  1993.         ATLTRACENOTIMPL(_T("IOleObjectImpl::SetColorScheme"));
  1994.     }
  1995. // Implementation
  1996. public:
  1997.     HRESULT OnPreVerbShow() { return S_OK; }
  1998.     HRESULT OnPostVerbShow() { return S_OK; }
  1999.     HRESULT OnPreVerbInPlaceActivate() { return S_OK; }
  2000.     HRESULT OnPostVerbInPlaceActivate() { return S_OK; }
  2001.     HRESULT OnPreVerbUIActivate() { return S_OK; }
  2002.     HRESULT OnPostVerbUIActivate() { return S_OK; }
  2003.     HRESULT OnPreVerbHide() { return S_OK; }
  2004.     HRESULT OnPostVerbHide() { return S_OK; }
  2005.     HRESULT OnPreVerbOpen() { return S_OK; }
  2006.     HRESULT OnPostVerbOpen() { return S_OK; }
  2007.     HRESULT OnPreVerbDiscardUndo() { return S_OK; }
  2008.     HRESULT OnPostVerbDiscardUndo() { return S_OK; }
  2009. };
  2010.  
  2011. //local struct used for implementation
  2012. #pragma pack(push, 1)
  2013. struct _ATL_DLGTEMPLATEEX
  2014. {
  2015.     WORD dlgVer;
  2016.     WORD signature;
  2017.     DWORD helpID;
  2018.     DWORD exStyle;
  2019.     DWORD style;
  2020.     WORD cDlgItems;
  2021.     short x;
  2022.     short y;
  2023.     short cx;
  2024.     short cy;
  2025. };
  2026. #pragma pack(pop)
  2027.  
  2028. //////////////////////////////////////////////////////////////////////////////
  2029. // IPropertyPageImpl
  2030. template <class T>
  2031. class ATL_NO_VTABLE IPropertyPageImpl : public IPropertyPage
  2032. {
  2033.  
  2034. public:
  2035.     void SetDirty(BOOL bDirty)
  2036.     {
  2037.         T* pT = static_cast<T*>(this);
  2038.         if (pT->m_bDirty != bDirty)
  2039.         {
  2040.             pT->m_bDirty = bDirty;
  2041.             pT->m_pPageSite->OnStatusChange(bDirty ? PROPPAGESTATUS_DIRTY | PROPPAGESTATUS_VALIDATE : 0);
  2042.         }
  2043.     }
  2044.  
  2045.     IPropertyPageImpl()
  2046.     {
  2047.         T* pT = static_cast<T*>(this);
  2048.         pT->m_pPageSite = NULL;
  2049.         pT->m_size.cx = 0;
  2050.         pT->m_size.cy = 0;
  2051.         pT->m_dwTitleID = 0;
  2052.         pT->m_dwHelpFileID = 0;
  2053.         pT->m_dwDocStringID = 0;
  2054.         pT->m_dwHelpContext = 0;
  2055.         pT->m_ppUnk = NULL;
  2056.         pT->m_nObjects = 0;
  2057.         pT->m_bDirty = FALSE;
  2058.         pT->m_hWnd = NULL;
  2059.     }
  2060.  
  2061.     ~IPropertyPageImpl()
  2062.     {
  2063.         T* pT = static_cast<T*>(this);
  2064.         if (pT->m_pPageSite != NULL)
  2065.             pT->m_pPageSite->Release();
  2066.  
  2067.         for (UINT i = 0; i < m_nObjects; i++)
  2068.             pT->m_ppUnk[i]->Release();
  2069.  
  2070.         delete[] pT->m_ppUnk;
  2071.     }
  2072.  
  2073.     // IPropertyPage
  2074.     //
  2075.     STDMETHOD(SetPageSite)(IPropertyPageSite *pPageSite)
  2076.     {
  2077.         T* pT = static_cast<T*>(this);
  2078.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::SetPageSite\n"));
  2079.  
  2080.         if (!pPageSite && pT->m_pPageSite)
  2081.         {
  2082.             pT->m_pPageSite->Release();
  2083.             pT->m_pPageSite = NULL;
  2084.             return S_OK;
  2085.         }
  2086.  
  2087.         if (!pPageSite && !pT->m_pPageSite)
  2088.             return S_OK;
  2089.  
  2090.         if (pPageSite && pT->m_pPageSite)
  2091.         {
  2092.             ATLTRACE2(atlTraceControls,2,_T("Error : setting page site again with non NULL value\n"));
  2093.             return E_UNEXPECTED;
  2094.         }
  2095.  
  2096.         pT->m_pPageSite = pPageSite;
  2097.         pT->m_pPageSite->AddRef();
  2098.         return S_OK;
  2099.     }
  2100.     STDMETHOD(Activate)(HWND hWndParent, LPCRECT pRect, BOOL /* bModal */)
  2101.     {
  2102.         T* pT = static_cast<T*>(this);
  2103.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Activate\n"));
  2104.  
  2105.         if (pRect == NULL)
  2106.         {
  2107.             ATLTRACE2(atlTraceControls,2,_T("Error : Passed a NULL rect\n"));
  2108.             return E_POINTER;
  2109.         }
  2110.  
  2111.         pT->m_hWnd = pT->Create(hWndParent);
  2112.         Move(pRect);
  2113.  
  2114.         m_size.cx = pRect->right - pRect->left;
  2115.         m_size.cy = pRect->bottom - pRect->top;
  2116.  
  2117.         return S_OK;
  2118.  
  2119.     }
  2120.     STDMETHOD(Deactivate)( void)
  2121.     {
  2122.         T* pT = static_cast<T*>(this);
  2123.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Deactivate\n"));
  2124.  
  2125.         if (pT->m_hWnd)
  2126.         {
  2127.             ATLTRACE2(atlTraceControls,2,_T("Destroying Dialog\n"));
  2128.             if (::IsWindow(pT->m_hWnd))
  2129.                 pT->DestroyWindow();
  2130.             pT->m_hWnd = NULL;
  2131.         }
  2132.  
  2133.         return S_OK;
  2134.  
  2135.     }
  2136.     STDMETHOD(GetPageInfo)(PROPPAGEINFO *pPageInfo)
  2137.     {
  2138.         T* pT = static_cast<T*>(this);
  2139.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::GetPageInfo\n"));
  2140.  
  2141.         if (pPageInfo == NULL)
  2142.         {
  2143.             ATLTRACE2(atlTraceControls,2,_T("Error : PROPPAGEINFO passed == NULL\n"));
  2144.             return E_POINTER;
  2145.         }
  2146.  
  2147.         HRSRC hRsrc = FindResource(_Module.GetResourceInstance(),
  2148.                                    MAKEINTRESOURCE(T::IDD), RT_DIALOG);
  2149.         if (hRsrc == NULL)
  2150.         {
  2151.             ATLTRACE2(atlTraceControls,2,_T("Could not find resource template\n"));
  2152.             return E_UNEXPECTED;
  2153.         }
  2154.  
  2155.         HGLOBAL hGlob = LoadResource(_Module.GetResourceInstance(), hRsrc);
  2156.         DLGTEMPLATE* pDlgTempl = (DLGTEMPLATE*)LockResource(hGlob);
  2157.         if (pDlgTempl == NULL)
  2158.         {
  2159.             ATLTRACE2(atlTraceControls,2,_T("Could not load resource template\n"));
  2160.             return E_UNEXPECTED;
  2161.         }
  2162.         AtlGetDialogSize(pDlgTempl, &m_size);
  2163.  
  2164.         pPageInfo->cb = sizeof(PROPPAGEINFO);
  2165.         pPageInfo->pszTitle = LoadStringHelper(pT->m_dwTitleID);
  2166.         pPageInfo->size = m_size;
  2167.         pPageInfo->pszHelpFile = LoadStringHelper(pT->m_dwHelpFileID);
  2168.         pPageInfo->pszDocString = LoadStringHelper(pT->m_dwDocStringID);
  2169.         pPageInfo->dwHelpContext = pT->m_dwHelpContext;
  2170.  
  2171.         return S_OK;
  2172.     }
  2173.  
  2174.     STDMETHOD(SetObjects)(ULONG nObjects, IUnknown **ppUnk)
  2175.     {
  2176.         T* pT = static_cast<T*>(this);
  2177.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::SetObjects\n"));
  2178.  
  2179.         if (ppUnk == NULL)
  2180.             return E_POINTER;
  2181.  
  2182.         if (pT->m_ppUnk != NULL && pT->m_nObjects > 0)
  2183.         {
  2184.             for (UINT iObj = 0; iObj < pT->m_nObjects; iObj++)
  2185.                 pT->m_ppUnk[iObj]->Release();
  2186.  
  2187.             delete [] pT->m_ppUnk;
  2188.         }
  2189.  
  2190.         pT->m_ppUnk = NULL;
  2191.         ATLTRY(pT->m_ppUnk = new IUnknown*[nObjects]);
  2192.  
  2193.         if (pT->m_ppUnk == NULL)
  2194.             return E_OUTOFMEMORY;
  2195.  
  2196.         for (UINT i = 0; i < nObjects; i++)
  2197.         {
  2198.             ppUnk[i]->AddRef();
  2199.             pT->m_ppUnk[i] = ppUnk[i];
  2200.         }
  2201.  
  2202.         pT->m_nObjects = nObjects;
  2203.  
  2204.         return S_OK;
  2205.     }
  2206.     STDMETHOD(Show)(UINT nCmdShow)
  2207.     {
  2208.         T* pT = static_cast<T*>(this);
  2209.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Show\n"));
  2210.  
  2211.         if (pT->m_hWnd == NULL)
  2212.             return E_UNEXPECTED;
  2213.  
  2214.         ShowWindow(pT->m_hWnd, nCmdShow);
  2215.         return S_OK;
  2216.     }
  2217.     STDMETHOD(Move)(LPCRECT pRect)
  2218.     {
  2219.         T* pT = static_cast<T*>(this);
  2220.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Move\n"));
  2221.  
  2222.         if (pT->m_hWnd == NULL)
  2223.             return E_UNEXPECTED;
  2224.  
  2225.         if (pRect == NULL)
  2226.             return E_POINTER;
  2227.  
  2228.         MoveWindow(pT->m_hWnd, pRect->left, pRect->top, pRect->right - pRect->left,
  2229.                  pRect->bottom - pRect->top, TRUE);
  2230.  
  2231.         return S_OK;
  2232.  
  2233.     }
  2234.     STDMETHOD(IsPageDirty)(void)
  2235.     {
  2236.         T* pT = static_cast<T*>(this);
  2237.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::IsPageDirty\n"));
  2238.         return pT->m_bDirty ? S_OK : S_FALSE;
  2239.     }
  2240.     STDMETHOD(Apply)(void)
  2241.     {
  2242.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Apply\n"));
  2243.         return S_OK;
  2244.     }
  2245.     STDMETHOD(Help)(LPCOLESTR pszHelpDir)
  2246.     {
  2247.         T* pT = static_cast<T*>(this);
  2248.         USES_CONVERSION;
  2249.  
  2250. #if defined(_WIN32_WCE)
  2251. // WinCE: No WinHelp
  2252.         RETAILMSG(1, (TEXT("IPropertyPageImpl::Help: Not implemented\r\n")));
  2253.         return E_NOTIMPL;
  2254. #else // _WIN32_WCE
  2255.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Help\n"));
  2256.         CComBSTR szFullFileName(pszHelpDir);
  2257.         LPOLESTR szFileName = LoadStringHelper(pT->m_dwHelpFileID);
  2258.         szFullFileName.Append(OLESTR("\\"));
  2259.         szFullFileName.Append(szFileName);
  2260.         CoTaskMemFree(szFileName);
  2261.         WinHelp(pT->m_hWnd, OLE2CT(szFullFileName), HELP_CONTEXTPOPUP, NULL);
  2262.         return S_OK;
  2263. #endif // _WIN32_WCE
  2264.     }
  2265.     STDMETHOD(TranslateAccelerator)(MSG *pMsg)
  2266.     {
  2267.         ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::TranslateAccelerator\n"));
  2268.         T* pT = static_cast<T*>(this);
  2269.         if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
  2270.             (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
  2271.             return S_FALSE;
  2272.  
  2273.         return (IsDialogMessage(pT->m_hWnd, pMsg)) ? S_OK : S_FALSE;
  2274.     }
  2275.  
  2276.     IPropertyPageSite* m_pPageSite;
  2277.     IUnknown** m_ppUnk;
  2278.     ULONG m_nObjects;
  2279.     SIZE m_size;
  2280.     UINT m_dwTitleID;
  2281.     UINT m_dwHelpFileID;
  2282.     UINT m_dwDocStringID;
  2283.     DWORD m_dwHelpContext;
  2284.     BOOL m_bDirty;
  2285.  
  2286. //methods
  2287. public:
  2288.  
  2289.     BEGIN_MSG_MAP(IPropertyPageImpl<T>)
  2290.         WCE_DEL MESSAGE_HANDLER(WM_STYLECHANGING, OnStyleChange)
  2291.     END_MSG_MAP()
  2292.  
  2293. #if !defined(_WIN32_WCE)
  2294.     LRESULT OnStyleChange(UINT, WPARAM wParam, LPARAM lParam, BOOL&)
  2295.     {
  2296.         if (wParam == GWL_EXSTYLE)
  2297.         {
  2298.             LPSTYLESTRUCT lpss = (LPSTYLESTRUCT) lParam;
  2299.             lpss->styleNew |= WS_EX_CONTROLPARENT;
  2300.             return 0;
  2301.         }
  2302.         return 1;
  2303.     }
  2304. #endif // _WIN32_WCE
  2305.  
  2306.     LPOLESTR LoadStringHelper(UINT idRes)
  2307.     {
  2308.         USES_CONVERSION;
  2309.  
  2310.         TCHAR szTemp[_MAX_PATH];
  2311.         LPOLESTR sz;
  2312.         sz = (LPOLESTR)CoTaskMemAlloc(_MAX_PATH*sizeof(OLECHAR));
  2313.         if (sz == NULL)
  2314.             return NULL;
  2315.         sz[0] = NULL;
  2316.  
  2317.         if (LoadString(_Module.GetResourceInstance(), idRes, szTemp, _MAX_PATH))
  2318.             ocscpy(sz, T2OLE(szTemp));
  2319.         else
  2320.         {
  2321.             ATLTRACE2(atlTraceControls,2,_T("Error : Failed to load string from res\n"));
  2322.         }
  2323.  
  2324.         return sz;
  2325.     }
  2326. };
  2327.  
  2328.  
  2329. //////////////////////////////////////////////////////////////////////////////
  2330. // IPropertyPage2Impl
  2331. template <class T>
  2332. class ATL_NO_VTABLE IPropertyPage2Impl : public IPropertyPageImpl<T>
  2333. {
  2334. public:
  2335.  
  2336.     STDMETHOD(EditProperty)(DISPID dispID)
  2337.     {
  2338.         ATLTRACENOTIMPL(_T("IPropertyPage2Impl::EditProperty\n"));
  2339.     }
  2340. };
  2341.  
  2342.  
  2343.  
  2344. //////////////////////////////////////////////////////////////////////////////
  2345. // IPerPropertyBrowsingImpl
  2346. template <class T>
  2347. class ATL_NO_VTABLE IPerPropertyBrowsingImpl : public IPerPropertyBrowsing
  2348. {
  2349. public:
  2350.     STDMETHOD(GetDisplayString)(DISPID dispID,BSTR *pBstr)
  2351.     {
  2352.         ATLTRACE2(atlTraceControls,2,_T("IPerPropertyBrowsingImpl::GetDisplayString\n"));
  2353.         T* pT = static_cast<T*>(this);
  2354.         *pBstr = NULL;
  2355.         CComVariant var;
  2356.         if (FAILED(CComDispatchDriver::GetProperty(pT, dispID, &var)))
  2357.             return S_FALSE;
  2358.  
  2359.         BSTR bstrTemp = var.bstrVal;
  2360.         if (var.vt != VT_BSTR)
  2361.         {
  2362.             CComVariant varDest;
  2363.             if (FAILED(::VariantChangeType(&varDest, &var, VARIANT_NOVALUEPROP, VT_BSTR)))
  2364.                 return S_FALSE;
  2365.             bstrTemp = varDest.bstrVal;
  2366.         }
  2367.         *pBstr = SysAllocString(bstrTemp);
  2368.         if (*pBstr == NULL)
  2369.             return E_OUTOFMEMORY;
  2370.         return S_OK;
  2371.     }
  2372.  
  2373.     STDMETHOD(MapPropertyToPage)(DISPID dispID, CLSID *pClsid)
  2374.     {
  2375.         ATLTRACE2(atlTraceControls,2,_T("IPerPropertyBrowsingImpl::MapPropertyToPage\n"));
  2376.         ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
  2377.         ATLASSERT(pMap != NULL);
  2378.         for (int i = 0; pMap[i].pclsidPropPage != NULL; i++)
  2379.         {
  2380.             if (pMap[i].szDesc == NULL)
  2381.                 continue;
  2382.  
  2383.             // reject data entry types
  2384.             if (pMap[i].dwSizeData != 0)
  2385.                 continue;
  2386.  
  2387.             if (pMap[i].dispid == dispID)
  2388.             {
  2389.                 ATLASSERT(pMap[i].pclsidPropPage != NULL);
  2390.                 *pClsid = *(pMap[i].pclsidPropPage);
  2391.                 return S_OK;
  2392.             }
  2393.         }
  2394.         *pClsid = CLSID_NULL;
  2395.         return E_INVALIDARG;
  2396.     }
  2397.     STDMETHOD(GetPredefinedStrings)(DISPID dispID, CALPOLESTR *pCaStringsOut,CADWORD *pCaCookiesOut)
  2398.     {
  2399.         dispID;
  2400.         ATLTRACE2(atlTraceControls,2,_T("IPerPropertyBrowsingImpl::GetPredefinedStrings\n"));
  2401.         if (pCaStringsOut == NULL || pCaCookiesOut == NULL)
  2402.             return E_POINTER;
  2403.  
  2404.         pCaStringsOut->cElems = 0;
  2405.         pCaStringsOut->pElems = NULL;
  2406.         pCaCookiesOut->cElems = 0;
  2407.         pCaCookiesOut->pElems = NULL;
  2408.         return S_OK;
  2409.     }
  2410.     STDMETHOD(GetPredefinedValue)(DISPID /*dispID*/, DWORD /*dwCookie*/, VARIANT* /*pVarOut*/)
  2411.     {
  2412.         ATLTRACENOTIMPL(_T("IPerPropertyBrowsingImpl::GetPredefinedValue"));
  2413.     }
  2414. };
  2415.  
  2416. //////////////////////////////////////////////////////////////////////////////
  2417. // IViewObjectExImpl
  2418. template <class T>
  2419. class ATL_NO_VTABLE IViewObjectExImpl : public IViewObjectEx
  2420. {
  2421. public:
  2422.     STDMETHOD(Draw)(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
  2423.                     DVTARGETDEVICE *ptd, HDC hicTargetDev, HDC hdcDraw,
  2424.                     LPCRECTL prcBounds, LPCRECTL prcWBounds,
  2425.                     BOOL (__stdcall * /*pfnContinue*/)(DWORD dwContinue),
  2426.                     DWORD /*dwContinue*/)
  2427.     {
  2428.         T* pT = static_cast<T*>(this);
  2429.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::Draw\n"));
  2430.         return pT->IViewObject_Draw(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw,
  2431.             prcBounds, prcWBounds);
  2432.     }
  2433.  
  2434.     STDMETHOD(GetColorSet)(DWORD /* dwDrawAspect */,LONG /* lindex */, void* /* pvAspect */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, LOGPALETTE** /* ppColorSet */)
  2435.     {
  2436.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetColorSet"));
  2437.     }
  2438.     STDMETHOD(Freeze)(DWORD /* dwDrawAspect */, LONG /* lindex */, void* /* pvAspect */,DWORD* /* pdwFreeze */)
  2439.     {
  2440.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::Freeze"));
  2441.     }
  2442.     STDMETHOD(Unfreeze)(DWORD /* dwFreeze */)
  2443.     {
  2444.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::Unfreeze"));
  2445.     }
  2446.     STDMETHOD(SetAdvise)(DWORD /* aspects */, DWORD /* advf */, IAdviseSink* pAdvSink)
  2447.     {
  2448.         T* pT = static_cast<T*>(this);
  2449.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::SetAdvise\n"));
  2450.         pT->m_spAdviseSink = pAdvSink;
  2451.         return S_OK;
  2452.     }
  2453.     STDMETHOD(GetAdvise)(DWORD* /* pAspects */, DWORD* /* pAdvf */, IAdviseSink** ppAdvSink)
  2454.     {
  2455.         T* pT = static_cast<T*>(this);
  2456.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::GetAdvise\n"));
  2457.         if (ppAdvSink != NULL)
  2458.         {
  2459.             *ppAdvSink = pT->m_spAdviseSink;
  2460.             if (pT->m_spAdviseSink)
  2461.                 pT->m_spAdviseSink.p->AddRef();
  2462.         }
  2463.         return S_OK;
  2464.     }
  2465.  
  2466.     // IViewObject2
  2467.     //
  2468.     STDMETHOD(GetExtent)(DWORD /* dwDrawAspect */, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, LPSIZEL lpsizel)
  2469.     {
  2470.         T* pT = static_cast<T*>(this);
  2471.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::GetExtent\n"));
  2472.         *lpsizel = pT->m_sizeExtent;
  2473.         return S_OK;
  2474.     }
  2475.  
  2476.     // IViewObjectEx
  2477.     //
  2478.     STDMETHOD(GetRect)(DWORD /* dwAspect */, LPRECTL /* pRect */)
  2479.     {
  2480.         ATLTRACENOTIMPL(_T("IViewObjectExImpl::GetRect"));
  2481.     }
  2482.  
  2483.     STDMETHOD(GetViewStatus)(DWORD* pdwStatus)
  2484.     {
  2485.         T* pT = static_cast<T*>(this);
  2486.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::GetViewStatus\n"));
  2487.         *pdwStatus = pT->_GetViewStatus();
  2488.         return S_OK;
  2489.     }
  2490.     STDMETHOD(QueryHitPoint)(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG /* lCloseHint */, DWORD *pHitResult)
  2491.     {
  2492.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::QueryHitPoint\n"));
  2493.         if (dwAspect == DVASPECT_CONTENT)
  2494.         {
  2495.             *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  2496.             return S_OK;
  2497.         }
  2498.         ATLTRACE2(atlTraceControls,2,_T("Wrong DVASPECT\n"));
  2499.         return E_FAIL;
  2500.     }
  2501.     STDMETHOD(QueryHitRect)(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT prcLoc, LONG /* lCloseHint */, DWORD* pHitResult)
  2502.     {
  2503.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::QueryHitRect\n"));
  2504.         if (dwAspect == DVASPECT_CONTENT)
  2505.         {
  2506.             RECT rc;
  2507.             *pHitResult = UnionRect(&rc, pRectBounds, prcLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  2508.             return S_OK;
  2509.         }
  2510.         ATLTRACE2(atlTraceControls,2,_T("Wrong DVASPECT\n"));
  2511.         return E_FAIL;
  2512.     }
  2513.     STDMETHOD(GetNaturalExtent)(DWORD dwAspect, LONG /* lindex */, DVTARGETDEVICE* /* ptd */, HDC /* hicTargetDev */, DVEXTENTINFO* pExtentInfo , LPSIZEL psizel)
  2514.     {
  2515.         T* pT = static_cast<T*>(this);
  2516.         ATLTRACE2(atlTraceControls,2,_T("IViewObjectExImpl::GetNaturalExtent\n"));
  2517.         HRESULT hRes = E_FAIL;
  2518.         if (pExtentInfo == NULL || psizel == NULL)
  2519.             hRes = E_POINTER;
  2520.         else if (dwAspect == DVASPECT_CONTENT)
  2521.         {
  2522.             if (pExtentInfo->dwExtentMode == DVEXTENT_CONTENT)
  2523.             {
  2524.                 *psizel = pT->m_sizeNatural;
  2525.                 hRes = S_OK;
  2526.             }
  2527.         }
  2528.         return hRes;
  2529.     }
  2530.  
  2531. public:
  2532. };
  2533.  
  2534. //////////////////////////////////////////////////////////////////////////////
  2535. // IOleInPlaceObjectWindowlessImpl
  2536. //
  2537. template <class T>
  2538. class ATL_NO_VTABLE IOleInPlaceObjectWindowlessImpl : public IOleInPlaceObjectWindowless
  2539. {
  2540. public:
  2541.     // IOleWindow
  2542.     //
  2543.  
  2544.     // Change IOleInPlaceActiveObject::GetWindow as well
  2545.     STDMETHOD(GetWindow)(HWND* phwnd)
  2546.     {
  2547.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::GetWindow\n"));
  2548.         T* pT = static_cast<T*>(this);
  2549.         HRESULT hRes = E_POINTER;
  2550.  
  2551.         if (pT->m_bWasOnceWindowless)
  2552.             return E_FAIL;
  2553.  
  2554.         if (phwnd != NULL)
  2555.         {
  2556.             *phwnd = pT->m_hWnd;
  2557.             hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK;
  2558.         }
  2559.         return hRes;
  2560.     }
  2561.     STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */)
  2562.     {
  2563.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ContextSensitiveHelp"));
  2564.     }
  2565.  
  2566.     // IOleInPlaceObject
  2567.     //
  2568.     STDMETHOD(InPlaceDeactivate)(void)
  2569.     {
  2570.         T* pT = static_cast<T*>(this);
  2571.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::InPlaceDeactivate\n"));
  2572.         return pT->IOleInPlaceObject_InPlaceDeactivate();
  2573.     }
  2574.     STDMETHOD(UIDeactivate)(void)
  2575.     {
  2576.         T* pT = static_cast<T*>(this);
  2577.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::UIDeactivate\n"));
  2578.         return pT->IOleInPlaceObject_UIDeactivate();
  2579.     }
  2580.     STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
  2581.     {
  2582.         T* pT = static_cast<T*>(this);
  2583.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::SetObjectRects\n"));
  2584.         return pT->IOleInPlaceObject_SetObjectRects(prcPos, prcClip);
  2585.     }
  2586.     STDMETHOD(ReactivateAndUndo)(void)
  2587.     {
  2588.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::ReactivateAndUndo"));
  2589.     }
  2590.  
  2591.     // IOleInPlaceObjectWindowless
  2592.     //
  2593.     STDMETHOD(OnWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
  2594.     {
  2595.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceObjectWindowlessImpl::OnWindowMessage\n"));
  2596.         T* pT = static_cast<T*>(this);
  2597.         BOOL b = pT->ProcessWindowMessage(pT->m_hWnd, msg, wParam, lParam, *plResult);
  2598.         return b ? S_OK : S_FALSE;
  2599.     }
  2600.  
  2601.     STDMETHOD(GetDropTarget)(IDropTarget** /* ppDropTarget */)
  2602.     {
  2603.         ATLTRACENOTIMPL(_T("IOleInPlaceObjectWindowlessImpl::GetDropTarget"));
  2604.     }
  2605. };
  2606.  
  2607.  
  2608. //////////////////////////////////////////////////////////////////////////////
  2609. // IOleInPlaceActiveObjectImpl
  2610. //
  2611. template <class T>
  2612. class ATL_NO_VTABLE IOleInPlaceActiveObjectImpl : public IOleInPlaceActiveObject
  2613. {
  2614. public:
  2615.     // IOleWindow
  2616.     //
  2617.  
  2618.     // Change IOleInPlaceObjectWindowless::GetWindow as well
  2619.     STDMETHOD(GetWindow)(HWND *phwnd)
  2620.     {
  2621.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::GetWindow\n"));
  2622.         T* pT = static_cast<T*>(this);
  2623.         HRESULT hRes = E_POINTER;
  2624.  
  2625.         if (pT->m_bWasOnceWindowless)
  2626.             return E_FAIL;
  2627.  
  2628.         if (phwnd != NULL)
  2629.         {
  2630.             *phwnd = pT->m_hWnd;
  2631.             hRes = (*phwnd == NULL) ? E_UNEXPECTED : S_OK;
  2632.         }
  2633.         return hRes;
  2634.     }
  2635.     STDMETHOD(ContextSensitiveHelp)(BOOL /* fEnterMode */)
  2636.     {
  2637.         ATLTRACENOTIMPL(_T("IOleInPlaceActiveObjectImpl::ContextSensitiveHelp"));
  2638.     }
  2639.  
  2640.     // IOleInPlaceActiveObject
  2641.     //
  2642.     STDMETHOD(TranslateAccelerator)(LPMSG pMsg)
  2643.     {
  2644.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::TranslateAccelerator\n"));
  2645.         T* pT = static_cast<T*>(this);
  2646.         HRESULT hRet = S_OK;
  2647.         if (pT->PreTranslateAccelerator(pMsg, hRet))
  2648.             return hRet;
  2649.         CComPtr<IOleControlSite> spCtlSite;
  2650.         hRet = pT->InternalGetSite(IID_IOleControlSite, (void**)&spCtlSite);
  2651.         if (SUCCEEDED(hRet))
  2652.         {
  2653.             if (spCtlSite != NULL)
  2654.             {
  2655.                 DWORD dwKeyMod = 0;
  2656.                 if (::GetKeyState(VK_SHIFT) < 0)
  2657.                     dwKeyMod += 1;    // KEYMOD_SHIFT
  2658.                 if (::GetKeyState(VK_CONTROL) < 0)
  2659.                     dwKeyMod += 2;    // KEYMOD_CONTROL
  2660.                 if (::GetKeyState(VK_MENU) < 0)
  2661.                     dwKeyMod += 4;    // KEYMOD_ALT
  2662.                 hRet = spCtlSite->TranslateAccelerator(pMsg, dwKeyMod);
  2663.             }
  2664.             else
  2665.                 hRet = S_FALSE;
  2666.         }
  2667.         return (hRet == S_OK) ? S_OK : S_FALSE;
  2668.     }
  2669.     STDMETHOD(OnFrameWindowActivate)(BOOL /* fActivate */)
  2670.     {
  2671.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::OnFrameWindowActivate\n"));
  2672.         return S_OK;
  2673.     }
  2674.     STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
  2675.     {
  2676.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::OnDocWindowActivate\n"));
  2677.         T* pT = static_cast<T*>(this);
  2678.         if (fActivate == FALSE)
  2679.             pT->IOleInPlaceObject_UIDeactivate();
  2680.         return S_OK;
  2681.     }
  2682.     STDMETHOD(ResizeBorder)(LPCRECT /* prcBorder */, IOleInPlaceUIWindow* /* pUIWindow */, BOOL /* fFrameWindow */)
  2683.     {
  2684.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::ResizeBorder\n"));
  2685.         return S_OK;
  2686.     }
  2687.     STDMETHOD(EnableModeless)(BOOL /* fEnable */)
  2688.     {
  2689.         ATLTRACE2(atlTraceControls,2,_T("IOleInPlaceActiveObjectImpl::EnableModeless\n"));
  2690.         return S_OK;
  2691.     }
  2692. };
  2693.  
  2694. //////////////////////////////////////////////////////////////////////////////
  2695. // IPointerInactiveImpl
  2696. template <class T>
  2697. class ATL_NO_VTABLE IPointerInactiveImpl : public IPointerInactive
  2698. {
  2699. public:
  2700.     // IPointerInactive
  2701.     //
  2702.     STDMETHOD(GetActivationPolicy)(DWORD *pdwPolicy)
  2703.     {
  2704.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::GetActivationPolicy"));
  2705.     }
  2706.     STDMETHOD(OnInactiveMouseMove)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg)
  2707.     {
  2708.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveMouseMove"));
  2709.     }
  2710.     STDMETHOD(OnInactiveSetCursor)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg, BOOL fSetAlways)
  2711.     {
  2712.         ATLTRACENOTIMPL(_T("IPointerInactiveImpl::OnInactiveSetCursor"));
  2713.     }
  2714. };
  2715.  
  2716. //////////////////////////////////////////////////////////////////////////////
  2717. // IRunnableObjectImpl
  2718. template <class T>
  2719. class ATL_NO_VTABLE IRunnableObjectImpl : public IRunnableObject
  2720. {
  2721. public:
  2722.     // IRunnableObject
  2723.     //
  2724.     STDMETHOD(GetRunningClass)(LPCLSID lpClsid)
  2725.     {
  2726.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::GetRunningClass\n"));
  2727.         *lpClsid = GUID_NULL;
  2728.         return E_UNEXPECTED;
  2729.     }
  2730.     STDMETHOD(Run)(LPBINDCTX)
  2731.     {
  2732.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::Run\n"));
  2733.         return S_OK;
  2734.     }
  2735.     virtual BOOL STDMETHODCALLTYPE IsRunning()
  2736.     {
  2737.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::IsRunning\n"));
  2738.         return TRUE;
  2739.     }
  2740.     STDMETHOD(LockRunning)(BOOL /*fLock*/, BOOL /*fLastUnlockCloses*/)
  2741.     {
  2742.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::LockRunning\n"));
  2743.         return S_OK;
  2744.     }
  2745.     STDMETHOD(SetContainedObject)(BOOL /*fContained*/)
  2746.     {
  2747.         ATLTRACE2(atlTraceControls,2,_T("IRunnableObjectImpl::SetContainedObject\n"));
  2748.         return S_OK;
  2749.     }
  2750. };
  2751.  
  2752.  
  2753. //////////////////////////////////////////////////////////////////////////////
  2754. // IDataObjectImpl
  2755. template <class T>
  2756. class ATL_NO_VTABLE IDataObjectImpl : public IDataObject
  2757. {
  2758. public:
  2759.     STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
  2760.     {
  2761.         ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::GetData\n"));
  2762.         T* pT = (T*) this;
  2763.         return pT->IDataObject_GetData(pformatetcIn, pmedium);
  2764.     }
  2765.     STDMETHOD(GetDataHere)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */)
  2766.     {
  2767.         ATLTRACENOTIMPL(_T("IDataObjectImpl::GetDataHere"));
  2768.     }
  2769.     STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */)
  2770.     {
  2771.         ATLTRACENOTIMPL(_T("IDataObjectImpl::QueryGetData"));
  2772.     }
  2773.     STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
  2774.     {
  2775.         ATLTRACENOTIMPL(_T("IDataObjectImpl::GetCanonicalFormatEtc"));
  2776.     }
  2777.     STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
  2778.     {
  2779.         ATLTRACENOTIMPL(_T("IDataObjectImpl::SetData"));
  2780.     }
  2781.     STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */)
  2782.     {
  2783.         ATLTRACENOTIMPL(_T("IDataObjectImpl::EnumFormatEtc"));
  2784.     }
  2785.     STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
  2786.         DWORD *pdwConnection)
  2787.     {
  2788. #if defined(_WIN32_WCE)
  2789. // WinCE: No CreateDataAdviseHolder
  2790.         RETAILMSG(1, (TEXT("IDataObjectImpl::DAdvise: Not implemented\r\n")));
  2791.         return E_NOTIMPL;
  2792. #else // _WIN32_WCE
  2793.         ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::DAdvise\n"));
  2794.         T* pT = static_cast<T*>(this);
  2795.         HRESULT hr = S_OK;
  2796.         if (pT->m_spDataAdviseHolder == NULL)
  2797.             hr = CreateDataAdviseHolder(&pT->m_spDataAdviseHolder);
  2798.  
  2799.         if (hr == S_OK)
  2800.             hr = pT->m_spDataAdviseHolder->Advise((IDataObject*)this, pformatetc, advf, pAdvSink, pdwConnection);
  2801.  
  2802.         return hr;
  2803. #endif // _WIN32_WCE
  2804.     }
  2805.     STDMETHOD(DUnadvise)(DWORD dwConnection)
  2806.     {
  2807.         ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::DUnadvise\n"));
  2808.         T* pT = static_cast<T*>(this);
  2809.         HRESULT hr = S_OK;
  2810.         if (pT->m_spDataAdviseHolder == NULL)
  2811.             hr = OLE_E_NOCONNECTION;
  2812.         else
  2813.             hr = pT->m_spDataAdviseHolder->Unadvise(dwConnection);
  2814.         return hr;
  2815.     }
  2816.     STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise)
  2817.     {
  2818.         ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::EnumDAdvise\n"));
  2819.         T* pT = static_cast<T*>(this);
  2820.         HRESULT hr = E_FAIL;
  2821.         if (pT->m_spDataAdviseHolder != NULL)
  2822.             hr = pT->m_spDataAdviseHolder->EnumAdvise(ppenumAdvise);
  2823.         return hr;
  2824.     }
  2825. };
  2826.  
  2827. //////////////////////////////////////////////////////////////////////////////
  2828. // IPropertyNotifySinkCP
  2829. template <class T, class CDV = CComDynamicUnkArray >
  2830. class ATL_NO_VTABLE IPropertyNotifySinkCP :
  2831.     public IConnectionPointImpl<T, &IID_IPropertyNotifySink, CDV>
  2832. {
  2833. public:
  2834.     typedef CFirePropNotifyEvent _ATL_PROP_NOTIFY_EVENT_CLASS;
  2835. };
  2836.  
  2837.  
  2838. #if !defined(_WIN32_WCE)
  2839. //////////////////////////////////////////////////////////////////////////////
  2840. // IObjectSafety
  2841. //
  2842. // 2nd template parameter is the supported safety e.g.
  2843. // INTERFACESAFE_FOR_UNTRUSTED_CALLER - safe for scripting
  2844. // INTERFACESAFE_FOR_UNTRUSTED_DATA   - safe for initialization from data
  2845.  
  2846. template <class T, DWORD dwSupportedSafety>
  2847. class ATL_NO_VTABLE IObjectSafetyImpl : public IObjectSafety
  2848. {
  2849. public:
  2850.     IObjectSafetyImpl()
  2851.     {
  2852.         m_dwCurrentSafety = 0;
  2853.     }
  2854.  
  2855.     STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  2856.     {
  2857.         ATLTRACE2(atlTraceControls,2,_T("IObjectSafetyImpl2::GetInterfaceSafetyOptions\n"));
  2858.         T* pT = static_cast<T*>(this);
  2859.         if (pdwSupportedOptions == NULL || pdwEnabledOptions == NULL)
  2860.             return E_POINTER;
  2861.         
  2862.         HRESULT hr;
  2863.         IUnknown* pUnk;
  2864.         // Check if we support this interface
  2865.         hr = pT->GetUnknown()->QueryInterface(riid, (void**)&pUnk);
  2866.         if (SUCCEEDED(hr))
  2867.         {
  2868.             // We support this interface so set the safety options accordingly
  2869.             pUnk->Release();    // Release the interface we just acquired
  2870.             *pdwSupportedOptions = dwSupportedSafety;
  2871.             *pdwEnabledOptions   = m_dwCurrentSafety;
  2872.         }
  2873.         else
  2874.         {
  2875.             // We don't support this interface
  2876.             *pdwSupportedOptions = 0;
  2877.             *pdwEnabledOptions   = 0;
  2878.         }
  2879.         return hr;
  2880.     }
  2881.     STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  2882.     {
  2883.         ATLTRACE2(atlTraceControls,2,_T("IObjectSafetyImpl2::SetInterfaceSafetyOptions\n"));
  2884.         T* pT = static_cast<T*>(this);
  2885.         IUnknown* pUnk;
  2886.         
  2887.         // Check if we support the interface and return E_NOINTEFACE if we don't
  2888.         if (FAILED(pT->GetUnknown()->QueryInterface(riid, (void**)&pUnk)))
  2889.             return E_NOINTERFACE;
  2890.         pUnk->Release();    // Release the interface we just acquired
  2891.         
  2892.         // If we are asked to set options we don't support then fail
  2893.         if (dwOptionSetMask & ~dwSupportedSafety)
  2894.             return E_FAIL;
  2895.  
  2896.         // Set the safety options we have been asked to
  2897.         m_dwCurrentSafety = m_dwCurrentSafety  & ~dwEnabledOptions | dwOptionSetMask;
  2898.         return S_OK;
  2899.     }
  2900.     DWORD m_dwCurrentSafety;
  2901. };
  2902.  
  2903. template <class T>
  2904. class ATL_NO_VTABLE IOleLinkImpl : public IOleLink
  2905. {
  2906.     STDMETHOD(SetUpdateOptions)(DWORD /* dwUpdateOpt */)
  2907.     {
  2908.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetUpdateOptions"));
  2909.     }
  2910.  
  2911.     STDMETHOD(GetUpdateOptions)(DWORD* /* pdwUpdateOpt */)
  2912.     {
  2913.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetUpdateOptions"));
  2914.     }
  2915.  
  2916.     STDMETHOD(SetSourceMoniker)(IMoniker* /* pmk */, REFCLSID /* rclsid */)
  2917.     {
  2918.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceMoniker"));
  2919.     }
  2920.  
  2921.     STDMETHOD(GetSourceMoniker)(IMoniker** /* ppmk */)
  2922.     {
  2923.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetSourceMoniker"));
  2924.     };
  2925.  
  2926.     STDMETHOD(SetSourceDisplayName)(LPCOLESTR /* pszStatusText */)
  2927.     {
  2928.         ATLTRACENOTIMPL(_T("IOleLinkImpl::SetSourceDisplayName"));
  2929.     }
  2930.  
  2931.     STDMETHOD(GetSourceDisplayName)(LPOLESTR *ppszDisplayName)
  2932.     {
  2933.         ATLTRACE2(atlTraceControls,2,_T("IOleLink::GetSourceDisplayName\n"));
  2934.         *ppszDisplayName = NULL;
  2935.         return E_FAIL;
  2936.     }
  2937.  
  2938.     STDMETHOD(BindToSource)(DWORD /* bindflags */, IBindCtx* /* pbc */)
  2939.     {
  2940.         ATLTRACENOTIMPL(_T("IOleLinkImpl::BindToSource\n"));
  2941.     };
  2942.  
  2943.     STDMETHOD(BindIfRunning)()
  2944.     {
  2945.         ATLTRACE2(atlTraceControls,2,_T("IOleLinkImpl::BindIfRunning\n"));
  2946.         return S_OK;
  2947.     };
  2948.  
  2949.     STDMETHOD(GetBoundSource)(IUnknown** /* ppunk */)
  2950.     {
  2951.         ATLTRACENOTIMPL(_T("IOleLinkImpl::GetBoundSource"));
  2952.     };
  2953.  
  2954.     STDMETHOD(UnbindSource)()
  2955.     {
  2956.         ATLTRACENOTIMPL(_T("IOleLinkImpl::UnbindSource"));
  2957.     };
  2958.  
  2959.     STDMETHOD(Update)(IBindCtx* /* pbc */)
  2960.     {
  2961.         ATLTRACENOTIMPL(_T("IOleLinkImpl::Update"));
  2962.     };
  2963. };
  2964.  
  2965. template <class T>
  2966. class ATL_NO_VTABLE CBindStatusCallback :
  2967.     public CComObjectRootEx<T::_ThreadModel::ThreadModelNoCS>,
  2968.     public IBindStatusCallback
  2969. {
  2970.     typedef void (T::*ATL_PDATAAVAILABLE)(CBindStatusCallback<T>* pbsc, BYTE* pBytes, DWORD dwSize);
  2971.  
  2972. public:
  2973.  
  2974. BEGIN_COM_MAP(CBindStatusCallback<T>)
  2975.     COM_INTERFACE_ENTRY(IBindStatusCallback)
  2976. END_COM_MAP()
  2977.  
  2978.     CBindStatusCallback()
  2979.     {
  2980.         m_pT = NULL;
  2981.         m_pFunc = NULL;
  2982.     }
  2983.     ~CBindStatusCallback()
  2984.     {
  2985.         ATLTRACE2(atlTraceControls,2,_T("~CBindStatusCallback\n"));
  2986.     }
  2987.  
  2988.     STDMETHOD(OnStartBinding)(DWORD dwReserved, IBinding *pBinding)
  2989.     {
  2990.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnStartBinding\n"));
  2991.         m_spBinding = pBinding;
  2992.         return S_OK;
  2993.     }
  2994.  
  2995.     STDMETHOD(GetPriority)(LONG *pnPriority)
  2996.     {
  2997.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::GetPriority"));
  2998.         HRESULT hr = S_OK;
  2999.         if (pnPriority)
  3000.             *pnPriority = THREAD_PRIORITY_NORMAL;
  3001.         else
  3002.             hr = E_INVALIDARG;
  3003.         return S_OK;
  3004.     }
  3005.  
  3006.     STDMETHOD(OnLowResource)(DWORD reserved)
  3007.     {
  3008.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnLowResource"));
  3009.         return S_OK;
  3010.     }
  3011.  
  3012.     STDMETHOD(OnProgress)(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
  3013.     {
  3014.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnProgress"));
  3015.         return S_OK;
  3016.     }
  3017.  
  3018.     STDMETHOD(OnStopBinding)(HRESULT hresult, LPCWSTR szError)
  3019.     {
  3020.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnStopBinding\n"));
  3021.         (m_pT->*m_pFunc)(this, NULL, 0);
  3022.         m_spBinding.Release();
  3023.         m_spBindCtx.Release();
  3024.         m_spMoniker.Release();
  3025.         return S_OK;
  3026.     }
  3027.  
  3028.     STDMETHOD(GetBindInfo)(DWORD *pgrfBINDF, BINDINFO *pbindInfo)
  3029.     {
  3030.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::GetBindInfo\n"));
  3031.  
  3032.         if (pbindInfo==NULL || pbindInfo->cbSize==0 || pgrfBINDF==NULL)
  3033.             return E_INVALIDARG;
  3034.  
  3035.         *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE |
  3036.             BINDF_GETNEWESTVERSION | BINDF_NOWRITECACHE;
  3037.  
  3038.         ULONG cbSize = pbindInfo->cbSize;        // remember incoming cbSize
  3039.         memset(pbindInfo, 0, cbSize);            // zero out structure
  3040.         pbindInfo->cbSize = cbSize;                // restore cbSize
  3041.         pbindInfo->dwBindVerb = BINDVERB_GET;    // set verb
  3042.         return S_OK;
  3043.     }
  3044.  
  3045.     STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
  3046.     {
  3047.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnDataAvailable\n"));
  3048.         HRESULT hr = S_OK;
  3049.  
  3050.         // Get the Stream passed
  3051.         if (BSCF_FIRSTDATANOTIFICATION & grfBSCF)
  3052.         {
  3053.             if (!m_spStream && pstgmed->tymed == TYMED_ISTREAM)
  3054.                 m_spStream = pstgmed->pstm;
  3055.         }
  3056.  
  3057.         DWORD dwRead = dwSize - m_dwTotalRead; // Minimum amount available that hasn't been read
  3058.         DWORD dwActuallyRead = 0;            // Placeholder for amount read during this pull
  3059.  
  3060.         // If there is some data to be read then go ahead and read them
  3061.         if (m_spStream)
  3062.         {
  3063.             if (dwRead > 0)
  3064.             {
  3065.                 BYTE* pBytes = NULL;
  3066.                 ATLTRY(pBytes = new BYTE[dwRead + 1]);
  3067.                 if (pBytes == NULL)
  3068.                     return E_OUTOFMEMORY;
  3069.                 hr = m_spStream->Read(pBytes, dwRead, &dwActuallyRead);
  3070.                 if (SUCCEEDED(hr))
  3071.                 {
  3072.                     pBytes[dwActuallyRead] = 0;
  3073.                     if (dwActuallyRead>0)
  3074.                     {
  3075.                         (m_pT->*m_pFunc)(this, pBytes, dwActuallyRead);
  3076.                         m_dwTotalRead += dwActuallyRead;
  3077.                     }
  3078.                 }
  3079.                 delete[] pBytes;
  3080.             }
  3081.         }
  3082.  
  3083.         if (BSCF_LASTDATANOTIFICATION & grfBSCF)
  3084.             m_spStream.Release();
  3085.         return hr;
  3086.     }
  3087.  
  3088.     STDMETHOD(OnObjectAvailable)(REFIID riid, IUnknown *punk)
  3089.     {
  3090.         ATLTRACE2(atlTraceControls,2,_T("CBindStatusCallback::OnObjectAvailable"));
  3091.         return S_OK;
  3092.     }
  3093.  
  3094.     HRESULT _StartAsyncDownload(BSTR bstrURL, IUnknown* pUnkContainer, BOOL bRelative)
  3095.     {
  3096.         m_dwTotalRead = 0;
  3097.         m_dwAvailableToRead = 0;
  3098.         HRESULT hr = S_OK;
  3099.         CComQIPtr<IServiceProvider, &IID_IServiceProvider> spServiceProvider(pUnkContainer);
  3100.         CComPtr<IBindHost>    spBindHost;
  3101.         CComPtr<IStream>    spStream;
  3102.         if (spServiceProvider)
  3103.             spServiceProvider->QueryService(SID_IBindHost, IID_IBindHost, (void**)&spBindHost);
  3104.  
  3105.         if (spBindHost == NULL)
  3106.         {
  3107.             if (bRelative)
  3108.                 return E_NOINTERFACE;  // relative asked for, but no IBindHost
  3109.             hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker);
  3110.             if (SUCCEEDED(hr))
  3111.                 hr = CreateBindCtx(0, &m_spBindCtx);
  3112.  
  3113.             if (SUCCEEDED(hr))
  3114.                 hr = RegisterBindStatusCallback(m_spBindCtx, static_cast<IBindStatusCallback*>(this), 0, 0L);
  3115.             else
  3116.                 m_spMoniker.Release();
  3117.  
  3118.             if (SUCCEEDED(hr))
  3119.                 hr = m_spMoniker->BindToStorage(m_spBindCtx, 0, IID_IStream, (void**)&spStream);
  3120.         }
  3121.         else
  3122.         {
  3123.             hr = CreateBindCtx(0, &m_spBindCtx);
  3124.             if (SUCCEEDED(hr))
  3125.                 hr = RegisterBindStatusCallback(m_spBindCtx, static_cast<IBindStatusCallback*>(this), 0, 0L);
  3126.  
  3127.             if (SUCCEEDED(hr))
  3128.             {
  3129.                 if (bRelative)
  3130.                     hr = spBindHost->CreateMoniker(bstrURL, m_spBindCtx, &m_spMoniker, 0);
  3131.                 else
  3132.                     hr = CreateURLMoniker(NULL, bstrURL, &m_spMoniker);
  3133.             }
  3134.  
  3135.             if (SUCCEEDED(hr))
  3136.             {
  3137.                 hr = spBindHost->MonikerBindToStorage(m_spMoniker, m_spBindCtx, static_cast<IBindStatusCallback*>(this), IID_IStream, (void**)&spStream);
  3138.                 ATLTRACE2(atlTraceControls,2,_T("Bound"));
  3139.             }
  3140.         }
  3141.         return hr;
  3142.     }
  3143.  
  3144.     HRESULT StartAsyncDownload(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE)
  3145.     {
  3146.         m_pT = pT;
  3147.         m_pFunc = pFunc;
  3148.         return  _StartAsyncDownload(bstrURL, pUnkContainer, bRelative);
  3149.     }
  3150.  
  3151.     static HRESULT Download(T* pT, ATL_PDATAAVAILABLE pFunc, BSTR bstrURL, IUnknown* pUnkContainer = NULL, BOOL bRelative = FALSE)
  3152.     {
  3153.         CComObject<CBindStatusCallback<T> > *pbsc;
  3154.         HRESULT hRes = CComObject<CBindStatusCallback<T> >::CreateInstance(&pbsc);
  3155.         if (FAILED(hRes))
  3156.             return hRes;
  3157.         return pbsc->StartAsyncDownload(pT, pFunc, bstrURL, pUnkContainer, bRelative);
  3158.     }
  3159.  
  3160.     CComPtr<IMoniker> m_spMoniker;
  3161.     CComPtr<IBindCtx> m_spBindCtx;
  3162.     CComPtr<IBinding> m_spBinding;
  3163.     CComPtr<IStream> m_spStream;
  3164.     T* m_pT;
  3165.     ATL_PDATAAVAILABLE m_pFunc;
  3166.     DWORD m_dwTotalRead;
  3167.     DWORD m_dwAvailableToRead;
  3168. };
  3169. #endif // _WIN32_WCE
  3170.  
  3171. #define IMPLEMENT_STOCKPROP(type, fname, pname, dispid) \
  3172.     HRESULT STDMETHODCALLTYPE put_##fname(type pname) \
  3173.     { \
  3174.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_%s\n"), #fname); \
  3175.         T* pT = (T*) this; \
  3176.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  3177.             return S_FALSE; \
  3178.         pT->m_##pname = pname; \
  3179.         pT->m_bRequiresSave = TRUE; \
  3180.         pT->FireOnChanged(dispid); \
  3181.         pT->FireViewChange(); \
  3182.         pT->SendOnDataChange(NULL); \
  3183.         return S_OK; \
  3184.     } \
  3185.     HRESULT STDMETHODCALLTYPE get_##fname(type* p##pname) \
  3186.     { \
  3187.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_%s\n"), #fname); \
  3188.         T* pT = (T*) this; \
  3189.         *p##pname = pT->m_##pname; \
  3190.         return S_OK; \
  3191.     }
  3192.  
  3193. #define IMPLEMENT_BOOL_STOCKPROP(fname, pname, dispid) \
  3194.     HRESULT STDMETHODCALLTYPE put_##fname(VARIANT_BOOL pname) \
  3195.     { \
  3196.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_%s\n"), #fname); \
  3197.         T* pT = (T*) this; \
  3198.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  3199.             return S_FALSE; \
  3200.         pT->m_##pname = pname; \
  3201.         pT->m_bRequiresSave = TRUE; \
  3202.         pT->FireOnChanged(dispid); \
  3203.         pT->FireViewChange(); \
  3204.         pT->SendOnDataChange(NULL); \
  3205.         return S_OK; \
  3206.     } \
  3207.     HRESULT STDMETHODCALLTYPE get_##fname(VARIANT_BOOL* p##pname) \
  3208.     { \
  3209.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_%s\n"), #fname); \
  3210.         T* pT = (T*) this; \
  3211.         *p##pname = pT->m_##pname ? VARIANT_TRUE : VARIANT_FALSE; \
  3212.         return S_OK; \
  3213.     }
  3214.  
  3215. #define IMPLEMENT_BSTR_STOCKPROP(fname, pname, dispid) \
  3216.     HRESULT STDMETHODCALLTYPE put_##fname(BSTR pname) \
  3217.     { \
  3218.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_%s\n"), #fname); \
  3219.         T* pT = (T*) this; \
  3220.         if (pT->FireOnRequestEdit(dispid) == S_FALSE) \
  3221.             return S_FALSE; \
  3222.         if (*(&(pT->m_##pname)) != NULL) \
  3223.             SysFreeString(*(&(pT->m_##pname))); \
  3224.         *(&(pT->m_##pname)) = SysAllocString(pname); \
  3225.         pT->m_bRequiresSave = TRUE; \
  3226.         pT->FireOnChanged(dispid); \
  3227.         pT->FireViewChange(); \
  3228.         pT->SendOnDataChange(NULL); \
  3229.         return S_OK; \
  3230.     } \
  3231.     HRESULT STDMETHODCALLTYPE get_##fname(BSTR* p##pname) \
  3232.     { \
  3233.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_%s\n"), #fname); \
  3234.         T* pT = (T*) this; \
  3235.         *p##pname = SysAllocString(pT->m_##pname); \
  3236.         return S_OK; \
  3237.     }
  3238.  
  3239.  
  3240. template < class T, class InterfaceName, const IID* piid, const GUID* plibid>
  3241. class ATL_NO_VTABLE CStockPropImpl : public IDispatchImpl< InterfaceName, piid, plibid >
  3242. {
  3243. public:
  3244.     // Font
  3245.     HRESULT STDMETHODCALLTYPE put_Font(IFontDisp* pFont)
  3246.     {
  3247.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_Font\n"));
  3248.         T* pT = (T*) this;
  3249.         if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE)
  3250.             return S_FALSE;
  3251.         pT->m_pFont = 0;
  3252.         if (pFont)
  3253.         {
  3254.             CComQIPtr<IFont, &IID_IFont> p(pFont);
  3255.             if (p)
  3256.             {
  3257.                 CComPtr<IFont> pFont;
  3258.                 p->Clone(&pFont);
  3259.                 if (pFont)
  3260.                     pFont->QueryInterface(IID_IFontDisp, (void**) &pT->m_pFont);
  3261.             }
  3262.         }
  3263.         pT->m_bRequiresSave = TRUE;
  3264.         pT->FireOnChanged(DISPID_FONT);
  3265.         pT->FireViewChange();
  3266.         pT->SendOnDataChange(NULL);
  3267.         return S_OK;
  3268.     }
  3269.     HRESULT STDMETHODCALLTYPE putref_Font(IFontDisp* pFont)
  3270.     {
  3271.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::putref_Font\n"));
  3272.         T* pT = (T*) this;
  3273.         if (pT->FireOnRequestEdit(DISPID_FONT) == S_FALSE)
  3274.             return S_FALSE;
  3275.         pT->m_pFont = pFont;
  3276.         pT->m_bRequiresSave = TRUE;
  3277.         pT->FireOnChanged(DISPID_FONT);
  3278.         pT->FireViewChange();
  3279.         pT->SendOnDataChange(NULL);
  3280.         return S_OK;
  3281.     }
  3282.     HRESULT STDMETHODCALLTYPE get_Font(IFontDisp** ppFont)
  3283.     {
  3284.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_Font\n"));
  3285.         T* pT = (T*) this;
  3286.         *ppFont = pT->m_pFont;
  3287.         if (*ppFont != NULL)
  3288.             (*ppFont)->AddRef();
  3289.         return S_OK;
  3290.     }
  3291.     // Picture
  3292.     HRESULT STDMETHODCALLTYPE put_Picture(IPictureDisp* pPicture)
  3293.     {
  3294. #if defined(_WIN32_WCE)
  3295. // WinCE: No OleLoadPicture
  3296.         RETAILMSG(1, (TEXT("CStockPropImpl::put_Picture: Not implemented\r\n")));
  3297.         return E_NOTIMPL;
  3298. #else
  3299.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_Picture\n"));
  3300.         T* pT = (T*) this;
  3301.         if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE)
  3302.             return S_FALSE;
  3303.         pT->m_pPicture = 0;
  3304.         if (pPicture)
  3305.         {
  3306.             CComQIPtr<IPersistStream, &IID_IPersistStream> p(pPicture);
  3307.             if (p)
  3308.             {
  3309.                 ULARGE_INTEGER l;
  3310.                 p->GetSizeMax(&l);
  3311.                 HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart);
  3312.                 if (hGlob)
  3313.                 {
  3314.                     CComPtr<IStream> spStream;
  3315.                     CreateStreamOnHGlobal(hGlob, TRUE, &spStream);
  3316.                     if (spStream)
  3317.                     {
  3318.                         if (SUCCEEDED(p->Save(spStream, FALSE)))
  3319.                         {
  3320.                             LARGE_INTEGER l;
  3321.                             l.QuadPart = 0;
  3322.                             spStream->Seek(l, STREAM_SEEK_SET, NULL);
  3323.                             OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pPicture);
  3324.                         }
  3325.                         spStream.Release();
  3326.                     }
  3327.                     GlobalFree(hGlob);
  3328.                 }
  3329.             }
  3330.         }
  3331.         pT->m_bRequiresSave = TRUE;
  3332.         pT->FireOnChanged(DISPID_PICTURE);
  3333.         pT->FireViewChange();
  3334.         pT->SendOnDataChange(NULL);
  3335.         return S_OK;
  3336. #endif // _WIN32_WCE
  3337.     }
  3338.     HRESULT STDMETHODCALLTYPE putref_Picture(IPictureDisp* pPicture)
  3339.     {
  3340.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::putref_Picture\n"));
  3341.         T* pT = (T*) this;
  3342.         if (pT->FireOnRequestEdit(DISPID_PICTURE) == S_FALSE)
  3343.             return S_FALSE;
  3344.         pT->m_pPicture = pPicture;
  3345.         pT->m_bRequiresSave = TRUE;
  3346.         pT->FireOnChanged(DISPID_PICTURE);
  3347.         pT->FireViewChange();
  3348.         pT->SendOnDataChange(NULL);
  3349.         return S_OK;
  3350.     }
  3351.     HRESULT STDMETHODCALLTYPE get_Picture(IPictureDisp** ppPicture)
  3352.     {
  3353.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_Picture\n"));
  3354.         T* pT = (T*) this;
  3355.         *ppPicture = pT->m_pPicture;
  3356.         if (*ppPicture != NULL)
  3357.             (*ppPicture)->AddRef();
  3358.         return S_OK;
  3359.     }
  3360.     // MouseIcon
  3361.     HRESULT STDMETHODCALLTYPE put_MouseIcon(IPictureDisp* pPicture)
  3362.     {
  3363. #if defined(_WIN32_WCE)
  3364. // WinCE: No OleLoadPicture, etc.
  3365.         RETAILMSG(1, (TEXT("CStockPropImpl::put_MouseIcon: Not implemented\r\n")));
  3366.         return E_NOTIMPL;
  3367. #else // _WIN32_WCE
  3368.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_MouseIcon\n"));
  3369.         T* pT = (T*) this;
  3370.         if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE)
  3371.             return S_FALSE;
  3372.         pT->m_pMouseIcon = 0;
  3373.         if (pPicture)
  3374.         {
  3375.             CComQIPtr<IPersistStream, &IID_IPersistStream> p(pPicture);
  3376.             if (p)
  3377.             {
  3378.                 ULARGE_INTEGER l;
  3379.                 p->GetSizeMax(&l);
  3380.                 HGLOBAL hGlob = GlobalAlloc(GHND, l.LowPart);
  3381.                 if (hGlob)
  3382.                 {
  3383.                     CComPtr<IStream> spStream;
  3384.                     CreateStreamOnHGlobal(hGlob, TRUE, &spStream);
  3385.                     if (spStream)
  3386.                     {
  3387.                         if (SUCCEEDED(p->Save(spStream, FALSE)))
  3388.                         {
  3389.                             LARGE_INTEGER l;
  3390.                             l.QuadPart = 0;
  3391.                             spStream->Seek(l, STREAM_SEEK_SET, NULL);
  3392.                             OleLoadPicture(spStream, l.LowPart, FALSE, IID_IPictureDisp, (void**)&pT->m_pMouseIcon);
  3393.                         }
  3394.                         spStream.Release();
  3395.                     }
  3396.                     GlobalFree(hGlob);
  3397.                 }
  3398.             }
  3399.         }
  3400.         pT->m_bRequiresSave = TRUE;
  3401.         pT->FireOnChanged(DISPID_MOUSEICON);
  3402.         pT->FireViewChange();
  3403.         pT->SendOnDataChange(NULL);
  3404.         return S_OK;
  3405. #endif //_WIN32_WCE
  3406.     }
  3407.     HRESULT STDMETHODCALLTYPE putref_MouseIcon(IPictureDisp* pPicture)
  3408.     {
  3409.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::putref_MouseIcon\n"));
  3410.         T* pT = (T*) this;
  3411.         if (pT->FireOnRequestEdit(DISPID_MOUSEICON) == S_FALSE)
  3412.             return S_FALSE;
  3413.         pT->m_pMouseIcon = pPicture;
  3414.         pT->m_bRequiresSave = TRUE;
  3415.         pT->FireOnChanged(DISPID_MOUSEICON);
  3416.         pT->FireViewChange();
  3417.         pT->SendOnDataChange(NULL);
  3418.         return S_OK;
  3419.     }
  3420.     HRESULT STDMETHODCALLTYPE get_MouseIcon(IPictureDisp** ppPicture)
  3421.     {
  3422.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_MouseIcon\n"));
  3423.         T* pT = (T*) this;
  3424.         *ppPicture = pT->m_pMouseIcon;
  3425.         if (*ppPicture != NULL)
  3426.             (*ppPicture)->AddRef();
  3427.         return S_OK;
  3428.     }
  3429.     IMPLEMENT_STOCKPROP(OLE_COLOR, BackColor, clrBackColor, DISPID_BACKCOLOR)
  3430.     IMPLEMENT_STOCKPROP(OLE_COLOR, BorderColor, clrBorderColor, DISPID_BORDERCOLOR)
  3431.     IMPLEMENT_STOCKPROP(OLE_COLOR, FillColor, clrFillColor, DISPID_FILLCOLOR)
  3432.     IMPLEMENT_STOCKPROP(OLE_COLOR, ForeColor, clrForeColor, DISPID_FORECOLOR)
  3433.     IMPLEMENT_BOOL_STOCKPROP(AutoSize, bAutoSize, DISPID_AUTOSIZE)
  3434.     IMPLEMENT_BOOL_STOCKPROP(Valid, bValid, DISPID_VALID)
  3435.     IMPLEMENT_BOOL_STOCKPROP(Enabled, bEnabled, DISPID_ENABLED)
  3436.     IMPLEMENT_BOOL_STOCKPROP(TabStop, bTabStop, DISPID_TABSTOP)
  3437.     IMPLEMENT_BOOL_STOCKPROP(BorderVisible, bBorderVisible, DISPID_BORDERVISIBLE)
  3438.     IMPLEMENT_BSTR_STOCKPROP(Text, bstrText, DISPID_TEXT)
  3439.     IMPLEMENT_BSTR_STOCKPROP(Caption, bstrCaption, DISPID_CAPTION)
  3440.     HRESULT STDMETHODCALLTYPE put_Window(long /*hWnd*/)
  3441.     {
  3442.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_Window\n"));
  3443.         return E_FAIL;
  3444.     }
  3445.     HRESULT STDMETHODCALLTYPE get_Window(long* phWnd)
  3446.     {
  3447.         ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_Window\n"));
  3448.         T* pT = (T*) this;
  3449.         *phWnd = (long)pT->m_hWnd;
  3450.         return S_OK;
  3451.     }
  3452.     IMPLEMENT_STOCKPROP(LONG, BackStyle, nBackStyle, DISPID_BACKSTYLE)
  3453.     IMPLEMENT_STOCKPROP(LONG, BorderStyle, nBorderStyle, DISPID_BORDERSTYLE)
  3454.     IMPLEMENT_STOCKPROP(LONG, BorderWidth, nBorderWidth, DISPID_BORDERWIDTH)
  3455.     IMPLEMENT_STOCKPROP(LONG, DrawMode, nDrawMode, DISPID_DRAWMODE)
  3456.     IMPLEMENT_STOCKPROP(LONG, DrawStyle, nDrawStyle, DISPID_DRAWSTYLE)
  3457.     IMPLEMENT_STOCKPROP(LONG, DrawWidth, nDrawWidth, DISPID_DRAWWIDTH)
  3458.     IMPLEMENT_STOCKPROP(LONG, FillStyle, nFillStyle, DISPID_FILLSTYLE)
  3459.     IMPLEMENT_STOCKPROP(SHORT, Appearance, nAppearance, DISPID_APPEARANCE)
  3460.     IMPLEMENT_STOCKPROP(LONG, MousePointer, nMousePointer, DISPID_MOUSEPOINTER)
  3461.     IMPLEMENT_STOCKPROP(LONG, ReadyState, nReadyState, DISPID_READYSTATE)
  3462. };
  3463.  
  3464. #pragma pack(pop)
  3465.  
  3466. }; //namespace ATL
  3467.  
  3468. #ifndef _ATL_DLL_IMPL
  3469. #ifndef _ATL_DLL
  3470. #define _ATLCTL_IMPL
  3471. #endif
  3472. #endif
  3473.  
  3474. #endif // __ATLCTL_H__
  3475.  
  3476. #ifdef _ATLCTL_IMPL
  3477.  
  3478. #ifndef _ATL_DLL_IMPL
  3479. namespace ATL
  3480. {
  3481. #endif
  3482.  
  3483.  
  3484. //All exports go here
  3485.  
  3486.  
  3487. #ifndef _ATL_DLL_IMPL
  3488. }; //namespace ATL
  3489. #endif
  3490.  
  3491. //Prevent pulling in second time 
  3492. #undef _ATLCTL_IMPL
  3493.  
  3494. #endif // _ATLCTL_IMPL
  3495.  
  3496.